diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..0b59186 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,11 @@ +## 问题与改动 + +说明具体问题、最终行为和涉及的模块。 + +## 兼容性 + +说明注册 ID、存档、配置与依赖变化,以及必要的升级/回退步骤。 + +## 验证 + +列出实际执行的检查与结果;未执行的相关检查说明原因。 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ff00184..3d7ebb8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -2,29 +2,83 @@ name: Build on: [push, pull_request] +permissions: + contents: read + +concurrency: + group: build-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + jobs: build: runs-on: ubuntu-latest + timeout-minutes: 45 steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 with: fetch-depth: 0 fetch-tags: true + persist-credentials: false - name: Setup JDK 25 - uses: actions/setup-java@v4 + uses: actions/setup-java@cf277c60eb25467037889841efdb72551f06f6c3 # v4 with: java-version: '25' distribution: 'temurin' - name: Setup Gradle - uses: gradle/actions/setup-gradle@v4 + uses: gradle/actions/setup-gradle@ed408507eac070d1f99cc633dbcf757c94c7933a # v4 - # This is needed to be able to run ./gradlew below - # You can run `git update-index --chmod +x gradlew` then remove this step. - name: Make Gradle wrapper executable run: chmod +x ./gradlew - - name: Build with Gradle - run: ./gradlew build \ No newline at end of file + - name: Generate client resources + run: ./gradlew :datagen:runClientData + + - name: Generate server resources + run: ./gradlew :datagen:runServerData + + - name: Verify generated resource snapshots + run: | + python3 scripts/sync_generated_resources.py + git diff --exit-code -- src/core/resources src/wilderness/resources src/barren/resources + + - name: Build and run integration tests + run: ./gradlew build collectMods :verification:runGameTest + + - name: Verify supported installations + run: | + for modules in core core,wilderness core,barren core,wilderness,barren; do + ./gradlew :smoke:runGameTest -PtestModules="$modules" + done + + - name: Verify distributable module set + shell: bash + run: | + set -euo pipefail + test "$(find build/distributions/mods -maxdepth 1 -name '*.jar' | wc -l)" -eq 3 + for module in core wilderness barren; do + files=(build/distributions/mods/wild_wind_"${module}"-mc*.jar) + test "${#files[@]}" -eq 1 + test -f "${files[0]}" + done + + - name: Upload test reports + if: always() + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + with: + name: WildWind-test-reports + path: | + modules/*/build/test-results/**/*.xml + modules/*/build/reports/tests/** + modules/*/build/runs/**/results.xml + if-no-files-found: ignore + retention-days: 14 + + - name: Upload distributable mods + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + with: + name: WildWind-mc26.2 + path: build/distributions/mods/*.jar + if-no-files-found: error diff --git a/.gitignore b/.gitignore index b777c76..4b9835f 100644 --- a/.gitignore +++ b/.gitignore @@ -36,7 +36,28 @@ bin/ ### Minecraft Modding ### run/ +modules/*/logs/ !**/src/**/run/ **/src/generated/**/.cache/ repo/ !**/src/**/repo/ + +### Local-only files and generated caches ### +.idea/ +.cache/ +.tools/ +.codex/ +*.log +*.tmp +*.bak +*.zip +*.class +*.jar +!gradle/wrapper/gradle-wrapper.jar +.env +.env.* +!.env.example +logs/ +crash-reports/ +Thumbs.db +Desktop.ini diff --git a/.idea/dictionaries/project.xml b/.idea/dictionaries/project.xml deleted file mode 100644 index 6b2fe45..0000000 --- a/.idea/dictionaries/project.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - hfas - - - \ No newline at end of file diff --git a/CHANGE_LOG.MD b/CHANGE_LOG.MD index e2262ac..1e3dc15 100644 --- a/CHANGE_LOG.MD +++ b/CHANGE_LOG.MD @@ -1,3 +1,35 @@ +# 2026-10-24 · 树叶使用贴图原色 + +- 荒野的焚烬木与灵焰木树叶改用无染色方块模型,移除物品的固定橙色/青色叠色;材质按贴图原色显示,保留透明像素和正常光照。 +- 飘落叶片不再读取群系叶色,分别使用固定橙色/青色。同步修改模型生成器,重新生成资源时保留这一规则。 + +# 2026-10-24 · 署名属性书与附魔台熔炼 + +- 核心属性记录器将主手/副手的书与笔直接转换为署名书,书名显示“目标名称(注册ID)”,作者为玩家。保留原始/过滤笔记;满页不转换;已署名书不再次写入。 +- 长名称完整保存在物品显示名称中,内部标题遵守原版 32 字符上限,避免存档与同步错误。 +- 显式将熔炼加入附魔台候选标签,保留现有等级、权重及经验消耗规则。新增真实附魔台菜单测试,验证四类挖掘工具和普通书的随机获取及附魔应用。 + +# 2026-10-23 · 书与笔属性记录器 + +- 核心新增潜行右键方块/实体记录属性,保留书中原有页,剩余空间不足时不写入。 +- 支持硬度、基础爆炸抗性、工具、火焰、红石、活塞、注册 ID、燃料/加工时间、可再生名单等字段。 +- 读取当前原版硫方怪原型及实际物理属性修改器,支持数据包调整;不适用/未知项显示 ×。 +- 新增分页单元测试、3 组 GameTest,并验证核心单独安装和客户端实际字体排版。 + +--- + +# 2026-10-23 · 三模组拆分 + +- 按最新归属拆分 `wild_wind_core`、`wild_wind_wilderness`、`wild_wind_barren`,各有入口、注册代码、资源与发行 JAR。 +- 荒野/瘠土分别依赖核心;只有荒野需要 GeckoLib。保留共享创造分页和蟹钳/熔炼联动。 +- 杜鹃木、窑炉及通用玩法归核心;两种下界木材、生物、状态效果与焦灰植物归荒野;仙人球归瘠土。 +- 暂时移除自定义部件制箭系统及原版制箭台替换行为,保留已完成的延展药水箭。 +- 数据生成快照随源码保存;更新 README、进度、开发指南和 CI。 +- 本地验证:11 项单元测试、24 组 GameTest、四种服务端安装组合,核心/完整组合客户端资源加载通过。 +- 旧 `ww_hfas:*` 注册 ID 无自动存档迁移;升级前备份并用新世界验证。结构配置与结构资源兼容命名空间保留。 + +--- + # Changelog All notable changes to the Wild Wind Module project will be documented in this file. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..91e2329 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,9 @@ +# 贡献指南 + +从目标开发分支创建主题分支,通过 Pull Request 提交改动。提交说明应描述具体行为与原因;保持改动可审查,不提交 IDE 设置、凭据、运行世界、缓存或构建产物。遵守仓库已有分项许可并保留作者与资源来源。 + +功能放入对应模块:核心不反向依赖可选扩展;扩展分别依赖核心。公共交互通过核心 API、事件或数据标签完成。新增注册 ID 必须使用所属模块的命名空间,涉及 ID、配置或存档变更时说明迁移与回退方式。 + +使用 JDK 25 与仓库 Gradle Wrapper。构建、单元测试、GameTest、数据生成及四种安装组合命令见 [开发指南](docs/DEVELOPMENT.md)。修改生成器时提交生成资源快照,并验证重新生成后无差异。按改动范围更新测试、功能文档与进度。 + +提交前执行 `git diff --check` 和适用测试。PR 中写明问题、最终行为、验证结果及兼容性限制;等待 CI 通过和分支规则要求的审核。不要强制推送受保护分支或绕过审核。 diff --git a/PROGRESS.md b/PROGRESS.md new file mode 100644 index 0000000..3dc6b5a --- /dev/null +++ b/PROGRESS.md @@ -0,0 +1,103 @@ +# 原野之风 · 项目进度 + +最后更新:**2026-10-24** + +当前阶段:**功能开发与测试,尚未发布稳定版** + +运行环境:Minecraft **26.2** · NeoForge **26.2.0.93** · Java **25** · 模组版本 **1.0.1** + +## 进度总览 + +**当前已交付功能清单:19 / 19 项已实现** + +```text +已交付功能实现 [████████████████████] 100% 19 / 19 +本地单元测试 [████████████████████] 100% 12 / 12 通过 +本地游戏测试 [████████████████████] 100% 28 / 28 通过 +``` + +> 功能进度条只统计下面列出的 19 项已交付内容,包含本次开发及已合并的上游功能;不代表整个模组、未来规划或人工验收全部完成。测试进度表示已有测试的通过比例,不代表代码覆盖率。完整项目的最终范围尚未确定,因此不估算总完成百分比。 + +## 已落实的模块划分 + +| 编号 | 模组 ID | 功能归属 | +| --- | --- | --- | +| 0 核心 | `wild_wind_core` | 杜鹃木及功能方块、羊毛拆线、挣脱蜘蛛网、骷髅近战、耕地保护、窑炉、熔炼;另保留结构生成与七种材料;书与笔属性记录器 | +| 1 荒野更新 | `wild_wind_wilderness` | 灵焰木、焚烬木、泥猪、泥沼蟹、恐鱼、窒息、沉溺、焦灰草方块/焦土/焦灰草丛/焦灰枝条;保留延展药水箭 | +| 2 瘠土更新 | `wild_wind_barren` | 仙人球 | + +已拆分入口、代码、注册器、Mixin、资源、元数据与发行 JAR。荒野、瘠土分别依赖核心;只有荒野需要 GeckoLib。自定义部件制箭系统暂时移除。 + +## 已完成功能 + +| 编号 | 状态 | 功能 | 已实现内容 | +| --- | --- | --- | --- | +| 01 | ✅ | 版本升级与模块拆分 | 适配 Minecraft 26.2 / NeoForge;按最新归属输出三个独立模组,保留结构配置命名空间。 | +| 02 | ✅ | 可配置结构生成 | JSON 定义结构,独立 NBT 模板目录;支持群系、间距、概率、高度、旋转和地形条件;提供列表、已生成结构最近坐标查询与生成位置搜索。 | +| 03 | ✅ | 木材与植物基础内容 | 焚烬木、灵焰木、杜鹃木基础方块套件;树木配置、去皮、配方及部分燃料;已有植物方块注册。模组树叶的方块/物品使用贴图原色,落叶粒子固定颜色。其他木材配套及视觉整理见下方待办。 | +| 04 | ✅ | 泥猪 | 成年/幼年模型和贴图,原版猪动画与音效,繁殖与刷怪蛋,沼泽和红树林沼泽自然生成。ID:`wild_wind_wilderness:muddy_pig`。 | +| 05 | ✅ | 上游生物与道具整合 | 合并泥沼蟹、恐鱼、生物桶、刷怪蛋、万用蟹钳及延展药水;食人鱼显示名改为恐鱼,保留 `piranha` 路径,但新命名空间不自动兼容旧存档。 | +| 06 | ✅ | 七种普通物品 | 浮萍、鱿鱼须、熟鱿鱼须、煎蛋、烤种子、熟蛙腿、生蛙腿;图标与翻译齐备,按当前要求全部作为普通材料注册。 | +| 07 | ✅ | 羊毛拆线 | 任意颜色羊毛 + 剪刀无序合成 2 个线;返还剪刀,损耗 1 点耐久并受耐久附魔影响;支持自动合成器。 | +| 08 | ✅ | 蜘蛛网挣脱 | 通常连续移动 30 刻、下坠进入后 160 刻破网;停止移动或离开重置;排除蜘蛛、洞穴蜘蛛、旁观玩家与飞行中的创造玩家。 | +| 09 | ✅ | 沉溺、窒息与呼吸规则 | `sink` 限制名单内实体在流体中上浮;`choke` 加快缺氧;实现水下免缺氧名单、两份效果名单及蝌蚪/美西螈离水特例。 | +| 10 | ✅ | 熔炼附魔 | `melting` 可由附魔台随机附到挖掘工具或书;按熔炉配方转换挖掘掉落,每件消耗 1 点经验;精准采集优先,时运先计算数量;整次经验不足不触发。 | +| 11 | ✅ | 骷髅近战设定 | 骷髅、流浪者、沼骸、焦骸生成时有 10% 概率使用石剑与近战 AI;后三者分别附加缓慢、中毒、虚弱。 | +| 12 | ✅ | 耕地保护 | 穿戴摔落缓冲盔甲或具有缓降效果的实体落到耕地上时,不会使耕地退化。 | +| 13 | ✅ | 模组专属分页 | 模组物品统一进入“原野之风”创造分页;包括药水、两种延展箭和熔炼附魔书;全局搜索可用。 | +| 14 | ✅ | 窑炉 | 100 刻烧炼、原料筛选、燃料、漏斗、经验、比较器、命名与锁定;新生成石匠屋添加窑炉;暂用原版熔炉模型和界面。 | +| 15 | ✅ | 杜鹃木告示牌 | 站立/墙面放置,双面文字、染色、发光、涂蜡、含水与数据保护;配方、掉落和燃料;补齐 26.2 贴图布局。 | +| 16 | ✅ | 悬挂式杜鹃木告示牌 | 吊顶/墙面放置、链条及横杆行为,双面编辑、染色、发光、涂蜡;配方、掉落和燃料。 | +| 17 | ✅ | 杜鹃木展示架 | 三槽整组交换;红石连接交换快捷栏 3/6/9 格;比较器输出 0–7;漏斗、存档和底部对齐设置。 | +| 18 | ✅ | 延展之箭与实体 | `wild_wind_wilderness:tipped_arrow` / `wild_wind_wilderness:arrow`;普通 450 刻、长效 1200 刻;合成、交易、英雄礼物、弓弩与发射器;落地 600 刻后退化为普通箭。 | +| 19 | ✅ | 书与笔属性记录器 | 核心:潜行右键方块/实体,直接转换为署名属性书,显示“目标名称(注册ID)”,作者为玩家;保留笔记并分页,满页不转换;缺失项 ×;实际硫方怪原型与物理参数;可再生标签扩展。 | + +## 工程与验证记录 + +- [x] 私有仓库 `cuccuc377-dev/WildWindMod` 保留来源、代码、资源、测试及构建流程。 +- [x] 三个发行模块分别编译,开发生成器与测试模组不进入发行集合。 +- [x] 12 项单元测试、28 组综合 GameTest 通过,含署名书转换和真实附魔台熔炼获取。 +- [x] 核心、核心+荒野、核心+瘠土、全部模块四种服务端安装组合通过。 +- [x] 核心单独安装与全模块客户端完成资源加载,自动检查告示牌及已安装生物资源。 +- [x] 数据生成与快照同步流程已建立,普通构建无需预先生成资源。 +- [x] 移除自定义制箭台、菜单、方块实体、部件组件及旧区块替换逻辑。 +- [ ] 人工验收告示牌编辑、荧光文字、展示架物品显示,以及多人联机与长期存档。 + +测试统计为本次本地验证结果,不代表覆盖率。历史 CI 构建基线为 `aeccc22`;新拆分版本的远端状态以 GitHub Actions 为准。 + +## 后续事项与已知限制 + +| 状态 | 项目 | 当前情况 | +| --- | --- | --- | +| 暂时移除 | 自定义部件制箭系统 | 恢复时需重新设计并验证完整流程;延展药水箭保留。 | +| 待完成 | 其他木材配套 | 船、焚烬木/灵焰木告示牌、盆栽树苗未注册,不能作为已完成内容。 | +| 待整理 | 既有材质警告 | 客户端仍报告未注册木材占位模型、焦灰草方块的旧纹理缺失;本次未重绘材质。 | +| 待验证 | 存档迁移 | 新 `wild_wind_*` ID 未自动映射旧 `ww_hfas:*`,需备份并优先用新测试世界。 | +| 待统一 | 许可证元数据 | 构建属性中的许可标识与仓库分项声明有差异,待维护者决定。 | +| 待验收 | 稳定发布 | 多人联机、人工视觉及长期存档测试尚未完成。 | + +本次记录器验证:新增 1 项分页单元测试和 3 组 GameTest;核心独立安装和客户端实际字体排版检查通过。 + +## 功能文档索引 + +- [项目说明与获取命令](README.md) +- [书与笔属性记录器](docs/BOOK_INSPECTION.md) +- [结构生成配置与坐标查询](docs/STRUCTURES.md) +- [泥猪模型、生成与测试](docs/MUDDY_PIG.md) +- [合成、状态效果、附魔和生物规则](docs/GAMEPLAY.md) +- [窑炉](docs/KILN.md) +- [杜鹃木功能方块与延展之箭](docs/AZALEA_AND_REACH_ARROWS.md) +- [开发指南与待完善事项](docs/DEVELOPMENT.md) +- [原始功能需求](docs/specifications/) · [项目来源](docs/PROVENANCE.md) + +## 更新记录 + +| 日期 | 进度变更 | +| --- | --- | +| 2026-10-23 | 建立进度文档,汇总当前 19 项已交付功能、测试结果、GitHub 构建状态及未完成事项。 | +| 2026-10-23 | 模块规划更新为 0「核心」、1「荒野更新」、2「瘠土更新」,同步中英文名称(当时为规划,现已落实)。 | +| 2026-10-23 | 三个规划模组 ID 统一采用 `wild_wind_` 前缀:`wild_wind_core`、`wild_wind_wilderness`、`wild_wind_barren`(当时为规划,现已落实)。 | + +| 2026-10-23 | 按最新清单完成三模组拆分及四种安装组合验证,移除自定义制箭系统,更新资源快照与 CI。 | + +维护约定:每次交付功能后更新对应条目、统计分母、进度条和日期;测试结果注明已验证的提交或构建记录;仅完成注册或占位资源的功能继续标为开发中。 diff --git a/README.md b/README.md index e2552db..d9b7e10 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,130 @@ -# Wild Wind Modules 原野之风模块包 +# 原野之风 · Wild Wind -### Module List 模块列表 +Minecraft **26.2 / NeoForge 26.2.0.93 / Java 25** 模组项目。当前已按功能拆成三个可独立打包的模组,模组版本为 `1.0.1`。 -| name | note | ch name | note | -|:----:|:--------------------:|:-------:|:-------:| -| hfas | Wild Wind HFAS | | 原野之风函数库 | -| deco | Wild Wind Decoration | 装饰 | 原野之风装饰库 | -| adv | Wind Wind Adventure | 冒险 | 原野之风冒险库 | -| vpp | Wild Wind Vanilla++ | 原版修饰 | 原野之风原版库 | +[项目进度](PROGRESS.md) · [开发指南](docs/DEVELOPMENT.md) · [上游同步与升级](docs/UPSTREAM_SYNC.md) · [贡献指南](CONTRIBUTING.md) · [来源说明](docs/PROVENANCE.md) · [历史变更](CHANGE_LOG.MD) -[CHANGES](./CHANGE_LOG.MD) \ No newline at end of file +## 模块与安装 + +| 编号 | 模组 | 模组 ID | 当前功能 | +| --- | --- | --- | --- | +| 0 | 原野之风:核心 / Wild Wind:Core | `wild_wind_core` | 杜鹃木及告示牌、悬挂告示牌、展示架;羊毛拆线;挣脱蜘蛛网;骷髅近战;耕地保护;窑炉;熔炼魔咒;结构生成;七种普通材料;书与笔属性记录器 | +| 1 | 原野之风:荒野更新 / Wild Wind:Wilderness Update | `wild_wind_wilderness` | 灵焰木、焚烬木;泥猪、泥沼蟹、恐鱼及相关道具;窒息、沉溺及呼吸规则;焦灰草方块、焦土、焦灰草丛、焦灰枝条;已有延展药水与延展之箭 | +| 2 | 原野之风:瘠土更新 / Wild Wind:Barren Update | `wild_wind_barren` | 仙人球 | + +- 核心可单独安装。荒野、瘠土分别依赖同版本核心,可以任选一个,也可以一起安装。 +- 安装荒野时,还需要 **GeckoLib 5.5.4 的 Minecraft 26.2 NeoForge 版本**;仅安装核心或核心+瘠土不需要 GeckoLib。 +- 客户端和服务端安装相同组合。所有已安装模块的物品汇入核心的「原野之风」创造分页,保留全局搜索。荒野的万用蟹钳与核心熔炼附魔可以联动。 +- 结构生成和七种普通材料暂归核心;结构配置路径、指令和 `ww_structures` 结构资源命名空间继续保留。 + +**自定义部件制箭系统暂时移除**:制箭台、方块实体、菜单、箭头/箭杆/箭羽数据组件、原版制箭台替换事件及配置均已移除。原版制箭台保持原版行为。已经完成的延展药水与延展之箭仍在荒野更新中。 + +### 更新旧版本 + +移除旧 `ww_hfas` 和独立 `ww_structures` JAR,再按需要安装新模块。加载器会阻止新旧模组同时加载。 + +**此次更换了方块、物品、实体等注册 ID 的命名空间,没有实现旧 `ww_hfas:*` 存档自动迁移。请先备份旧存档,优先在新测试世界验证;旧内容、NBT 模板和数据包中的旧 ID 需要按模块改写。** 恐鱼的路径仍为 `piranha`,完整新 ID 为 `wild_wind_wilderness:piranha`。删除的自定义制箭台也不会自动恢复为原版方块。 + +## 获取与测试 + +开启作弊或具备管理员权限后,在创造模式「原野之风」分页获取物品,也可以使用命令: + +```mcfunction +/give @s wild_wind_core:azalea_planks +/give @s wild_wind_core:azalea_sign +/give @s wild_wind_core:azalea_hanging_sign +/give @s wild_wind_core:azalea_shelf +/give @s wild_wind_core:kiln +/give @s wild_wind_core:duckweed 64 +/enchant @s wild_wind_core:melting 1 +/give @s wild_wind_wilderness:blaze_planks +/give @s wild_wind_wilderness:soul_planks +/give @s wild_wind_wilderness:muddy_pig_spawn_egg +/summon wild_wind_wilderness:muddy_pig ~ ~ ~ +/summon wild_wind_wilderness:mudcrab ~ ~ ~ +/summon wild_wind_wilderness:piranha ~ ~ ~ +/effect give @s wild_wind_wilderness:sink 60 +/effect give @s wild_wind_wilderness:choke 60 +/give @s wild_wind_wilderness:tipped_arrow 64 +/give @s wild_wind_barren:tiny_cactus +``` + +带有对应模块命名空间的命令需要先安装该模块。熔炼命令需手持可附魔工具。 + +七种普通材料均在核心,暂不具有食用行为:`duckweed` 浮萍、`calamari` 鱿鱼须、`cooked_calamari` 熟鱿鱼须、`cooked_egg` 煎蛋、`baked_seeds` 烤种子、`cooked_frog_legs` 熟蛙腿、`frog_legs` 生蛙腿。 + +### 书与笔属性记录器(核心) + +手持书与笔,**Shift+右键方块/实体**,直接转换为署名属性书;书名为“目标名称(注册ID)”,作者为玩家,松开 Shift 后右键阅读。记录硬度、抗性、可燃性、活塞行为、挖掘工具、注册 ID、燃料时长、可再生性及硫方怪原型/物理参数等。已有笔记保留,满页不转换;署名后不可追加,下次记录需另一本书与笔。不适用或未知的属性显示“×”,无需管理员权限。 + +使用 `/give @s minecraft:writable_book` 获取测试用书。硫方怪分类和数值读取当前游戏数据,可再生性通过数据包标签扩展。详见 [记录器说明](docs/BOOK_INSPECTION.md)。 + +### 主要玩法 + +- 任意羊毛+剪刀无序合成 2 个线;返还剪刀,扣 1 点耐久并受耐久附魔影响,支持自动合成器。 +- 非蜘蛛/洞穴蜘蛛实体连续移动 30 刻挣脱接触的蜘蛛网,下坠进入需要 160 刻;停止移动或离开重置。旁观玩家与飞行中的创造玩家不触发。 +- 骷髅、流浪者、沼骸、焦骸生成时有 10% 概率换石剑;后三者近战分别造成 30 秒缓慢 I、4 秒中毒 I、30 秒虚弱 I。 +- 穿戴摔落缓冲盔甲或具有缓降效果时,落到耕地不会踩坏耕地。 +- 窑炉使用原版熔炉外观,每 100 刻烧炼一件符合条件的材料,支持漏斗、比较器、经验、命名及锁定,新生成石匠屋增加窑炉。 +- 熔炼 I 可通过附魔台随机获得,适用于挖掘工具,也可附到普通书上。按实际掉落先结算时运;精准采集优先,不进行熔炼。每件消耗 1 点经验,整次经验不足则不触发。 +- 泥猪在沼泽与红树林沼泽自然生成,权重 10、每群 2–4 只;使用原版猪的动画、声音与基础行为,支持繁殖。 +- 焚烬木、灵焰木树叶的方块和物品按贴图原色显示,不叠加群系或固定染色;落叶粒子分别固定为橙色、青色。保留正常光照与阴影。 +- 沉溺限制名单内生物在流体中上浮;窒息加快名单内生物水下缺氧,蝌蚪/美西螈仅离水时生效。完整名单见玩法文档。 + +## 配置结构生成 + +启动世界后,在实例目录创建 `config/ww_structures/`: + +```text +config/ww_structures/ +├── definitions/ # 每个结构一个 JSON +├── templates/ # 压缩 .nbt 结构模板,支持子目录 +│ └── example_ruins.nbt +└── example_ruins.json.disabled +``` + +把示例复制为 `definitions/example_ruins.json`,设置 `enabled: true`,重启世界/服务器。配置可指定模板文件、群系、间距、概率、高度、旋转和地形条件;只在符合条件的新区块生成。 + +```mcfunction +/wwstructure list +/wwstructure locate example_ruins +/wwstructure search example_ruins 16 +``` + +`locate` 查当前维度已记录生成结构的最近坐标;`search` 搜索可能尚未探索的生成位置。详细配置见 [结构生成指南](docs/STRUCTURES.md)。 + +## 从源码构建 + +资源快照已随源码保存,普通构建不必先运行数据生成。在仓库根目录执行: + +```powershell +.\gradlew.bat build collectMods +``` + +Linux / macOS 使用 `./gradlew`。三个发行 JAR 收集在 `build/distributions/mods/`: + +```text +wild_wind_core-mc26.2-1.0.1.jar +wild_wind_wilderness-mc26.2-1.0.1.jar +wild_wind_barren-mc26.2-1.0.1.jar +``` + +`datagen`、`verification`、`smoke` 是开发辅助项目,不安装到玩家实例,也不包含在上述发行目录。代码、资源分别位于 `src/core/`、`src/wilderness/`、`src/barren/`。 + +修改生成器后运行两类数据生成,再将结果同步回模块资源目录: + +```powershell +.\gradlew.bat :datagen:runClientData :datagen:runServerData +python scripts/sync_generated_resources.py +.\gradlew.bat build collectMods :verification:runGameTest +``` + +完整命令、四种安装组合测试与工程约定见 [开发指南](docs/DEVELOPMENT.md)。 + +## 功能文档 + +[结构生成](docs/STRUCTURES.md) · [泥猪](docs/MUDDY_PIG.md) · [玩法/效果/附魔](docs/GAMEPLAY.md) · [窑炉](docs/KILN.md) · [杜鹃木功能方块与延展之箭](docs/AZALEA_AND_REACH_ARROWS.md) + +## 来源与许可 + +本项目整理自 `Polari-Stars-MC/WildWindModule`,保留上游来源和贡献者信息,详见 [来源说明](docs/PROVENANCE.md)。仓库分项许可为 [GPL-3.0-only 代码许可](LICENSE_CODE) 与 [CC-BY-SA-4.0 资源许可](LICENSE_ASSETS),总说明见 [LICENSE](LICENSE)。发行元数据使用相同的 `GPL-3.0-only AND CC-BY-SA-4.0` 许可标识。 diff --git a/build.gradle.kts b/build.gradle.kts index 1688d3b..57b59c9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,178 +1,151 @@ import org.slf4j.event.Level.INFO -import java.util.Locale plugins { `java-library` - `maven-publish` - id("net.neoforged.moddev") version ("2.0.141") - idea + id("net.neoforged.moddev") version("2.0.148") base } - - -//tasks.named("wrapper").configure { -// distributionType = Wrapper.DistributionType.BIN -//} - -val minecraftVersion: String by rootProject -val minecraftVersionRange: String by rootProject -val modName: String by rootProject -val modLicense: String by rootProject - -val geocklibVersion: String by rootProject - -allprojects { +val minecraftVersion: String by project +val minecraftVersionRange: String by project +val neoVersion: String by project +val modVersion: String by project +val modLicense: String by project +val modGroupId: String by project +val geocklibVersion: String by project +val releaseModules = listOf("core", "wilderness", "barren") +val smokeModules = providers.gradleProperty("testModules").orElse("core").get().split(",") +require(smokeModules.contains("core") && smokeModules.all { it in releaseModules }) { + "testModules must include core and may include wilderness and/or barren" +} +subprojects { apply(plugin = "java-library") - apply(plugin = "maven-publish") - apply(plugin = "idea") apply(plugin = "net.neoforged.moddev") - apply(plugin = "base") - val modGroupId: String by project - val modId: String by project - var projectModId = rootProject.name + "_" + project.name.lowercase(Locale.ROOT) - val modVersion: String by project - val neoVersion: String by project - if (project == rootProject) return@allprojects group = modGroupId version = modVersion - configure { - archivesName = projectModId - + val module = name + val modId = if (module == "verification") "wild_wind_tests" else "wild_wind_$module" + val moduleDependencies = when (module) { + "core" -> emptyList() + "wilderness", "barren" -> listOf("core") + "smoke" -> smokeModules + else -> releaseModules } - - var generateModMetadata = tasks.register("generatedMetadata") { - val replaceProperties = mapOf( - "minecraft_version" to minecraftVersion, - "minecraft_version_range" to minecraftVersionRange, - "neo_version" to neoVersion, - "mod_id" to projectModId, - "mod_name" to modName, - "mod_license" to modLicense, - "mod_version" to modVersion, - "geocklib_version" to geocklibVersion - ) - inputs.properties(replaceProperties) - expand(replaceProperties) + val usesGecko = module in listOf("wilderness", "datagen", "verification") || (module == "smoke" && "wilderness" in smokeModules) + base { archivesName = "$modId-mc$minecraftVersion" } + java.toolchain.languageVersion = JavaLanguageVersion.of(25) + repositories { + mavenCentral() + exclusiveContent { + forRepository { maven { url = uri("https://dl.cloudsmith.io/public/geckolib3/geckolib/maven/") } } + filter { includeGroupAndSubgroups("com.geckolib") } + } + } + dependencies { + moduleDependencies.forEach { implementation(project(":$it")) } + compileOnly("org.projectlombok:lombok:1.18.44") + annotationProcessor("org.projectlombok:lombok:1.18.44") + if (usesGecko) implementation("com.geckolib:geckolib-neoforge-$minecraftVersion:$geocklibVersion") + testImplementation(platform("org.junit:junit-bom:5.13.4")) + testImplementation("org.junit.jupiter:junit-jupiter") + testRuntimeOnly("org.junit.platform:junit-platform-launcher") + } + val metadata = tasks.register("generatedMetadata") { + val titles = mapOf("core" to "Wild Wind:Core", "wilderness" to "Wild Wind:Wilderness Update", "barren" to "Wild Wind:Barren Update", "datagen" to "Wild Wind Data Generators", "verification" to "Wild Wind Integration Tests", "smoke" to "Wild Wind Installation Tests") + val extraDependencies = buildString { + moduleDependencies.forEach { dependency -> + append(""" + [[dependencies.$modId]] + modId="wild_wind_$dependency" + type="required" + versionRange="[$modVersion]" + ordering="AFTER" + side="BOTH" + """.trimIndent()) + append('\n') + } + if (usesGecko) append(""" + [[dependencies.$modId]] + modId="geckolib" + type="required" + versionRange="[$geocklibVersion,)" + ordering="NONE" + side="BOTH" + """.trimIndent()) + } + val mixins = when { + module in releaseModules -> "[[mixins]]\nconfig=\"$modId.mixins.json\"" + module == "verification" -> "[[mixins]]\nconfig=\"wild_wind_tests.mixins.json\"" + module == "smoke" -> "" + else -> "" + } + val properties = mapOf("mod_id" to modId, "mod_name" to titles.getValue(module), "mod_version" to modVersion, "mod_license" to modLicense, "neo_version" to neoVersion, "minecraft_version_range" to minecraftVersionRange, "module_dependencies" to extraDependencies, "module_mixins" to mixins) + inputs.properties(properties) + expand(properties) from(rootProject.file("src/templates")) - into("build/generated/sources/modMetadata") + into(layout.buildDirectory.dir("generated/sources/modMetadata")) } - - sourceSets { - rootProject.file("src/${project.name}/java").resolve(modGroupId.replace('.', '/')).mkdirs() main { - java { - srcDir(rootProject.file("src/${project.name}/java")) - } - resources { - srcDir(generateModMetadata) - srcDir(rootProject.file("build/generated/${project.name}/server")) - srcDir(rootProject.file("build/generated/${project.name}/client")) - srcDir(rootProject.file("src/${project.name}/resources")) - - exclude("**/*.bbmodel") - exclude("build/generated/**/.cache") - } + java.setSrcDirs(listOf(rootProject.file("src/$module/java"))) + resources.setSrcDirs(listOf(rootProject.file("src/$module/resources"))) + resources.srcDir(metadata) + resources.exclude("**/*.bbmodel", "**/.cache/**") } + test { java.srcDir(rootProject.file("src/$module/test")) } } - - repositories { - exclusiveContent { - forRepository { - maven { - name = "GeckoLib" - url = uri("https://dl.cloudsmith.io/public/geckolib3/geckolib/maven/") - } - } - - filter { - includeGroupAndSubgroups("com.geckolib") - } - } + tasks.withType().configureEach { options.encoding = "UTF-8" } + tasks.test { + useJUnitPlatform() + val directory = layout.buildDirectory.dir("test-runtime") + workingDir(directory) + doFirst { directory.get().asFile.mkdirs() } } - - java.toolchain.languageVersion = JavaLanguageVersion.of(25) - neoForge { version = neoVersion - - accessTransformers.from(rootProject.file("src/${project.name}/resources/META-INF/accesstransformer.cfg")) - + if (usesGecko) accessTransformers.from(rootProject.file("src/wilderness/resources/META-INF/accesstransformer.cfg")) + addModdingDependenciesTo(sourceSets.test.get()) + mods { register(modId) { sourceSet(sourceSets.main.get()) } } runs { - register("client") { - client() - systemProperty("neoforge.enabledGameTestNamespaces", projectModId) - gameDirectory = layout.buildDirectory.dir("runs/${project.name}/client").get().asFile - } - register("server") { - server() - programArgument("--nogui") - systemProperty("neoforge.enabledGameTestNamespaces", projectModId) - gameDirectory = layout.buildDirectory.dir("runs/${project.name}/server").get().asFile - } - register("clientData") { - clientData() - gameDirectory = layout.buildDirectory.dir("runs/${project.name}/datagen").get().asFile - programArguments.addAll( - listOf( - "--mod", projectModId, - "--all", - "--output", rootProject.file("build/generated/${project.name}/client").absolutePath, - "--existing", rootProject.file("src/${project.name}/resources").absolutePath, - ) - ) + register("client") { client() } + register("server") { server(); programArgument("--nogui") } + if (module == "datagen") { + register("clientData") { + clientData() + programArguments.addAll("--mod", modId, "--all", "--output", rootProject.file("build/generated/datagen/client").absolutePath) + } + register("serverData") { + serverData() + programArguments.addAll("--mod", modId, "--all", "--output", rootProject.file("build/generated/datagen/server").absolutePath) + } } - register("serverData") { - serverData() - gameDirectory = layout.buildDirectory.dir("runs/${project.name}/datagen").get().asFile - programArguments.addAll( - listOf( - "--mod", projectModId, - "--all", - "--output", rootProject.file("build/generated/${project.name}/server").absolutePath, - "--existing", rootProject.file("src/${project.name}/resources").absolutePath, - ) - ) + if (module in listOf("verification", "smoke")) { + register("gameTest") { + type = "gameTestServer" + programArguments.addAll("--tests", "$modId:*", "--report", "results.xml") + if (module == "smoke") systemProperty("wildwind.testModules", smokeModules.joinToString(",")) + } } configureEach { - systemProperty("forge.logging.markers", "REGISTRIES") + if (module == "smoke" && providers.gradleProperty("clientSmoke").orElse("false").get() == "true") { + systemProperty("wildwind.clientSmoke", "true") + } + val variant = if (module == "smoke") "/${smokeModules.joinToString("-")}" else "" + gameDirectory = layout.buildDirectory.dir("runs/$name$variant") logLevel.set(INFO) } } - - mods { - register(projectModId) { - sourceSet(sourceSets["main"]) - } - } - - } - - neoForge.ideSyncTask(generateModMetadata) - - val localRuntime by configurations.registering - - configurations { - runtimeClasspath { - extendsFrom(localRuntime.get()) - } - } - - dependencies { - compileOnly("org.projectlombok:lombok:1.18.44") - annotationProcessor("org.projectlombok:lombok:1.18.44") - implementation("com.geckolib:geckolib-neoforge-26.2:5.5.4") - } - - tasks.withType().configureEach { - options.encoding = "UTF-8" - } - - idea { - module { - isDownloadJavadoc = true - isDownloadSources = true + if (module == "verification") { + val prepare by tasks.registering(Sync::class) { + from(rootProject.file("src/verification/config")) + from(rootProject.file("src/core/resources/examples/example_ruins.nbt")) { into("ww_structures/templates") } + into(layout.buildDirectory.dir("runs/gameTest/config")) } + neoForge.runs.named("gameTest") { taskBefore(prepare) } } } +tasks.register("collectMods") { + description = "Collect only the three distributable mod JARs (no development tools)." + releaseModules.forEach { module -> from(project(":$module").tasks.named("jar")) } + into(layout.buildDirectory.dir("distributions/mods")) +} diff --git a/docs/AZALEA_AND_REACH_ARROWS.md b/docs/AZALEA_AND_REACH_ARROWS.md new file mode 100644 index 0000000..6e99790 --- /dev/null +++ b/docs/AZALEA_AND_REACH_ARROWS.md @@ -0,0 +1,83 @@ +> 模块归属:杜鹃木告示牌、悬挂告示牌、展示架在核心;延展药水与延展之箭在荒野。自定义部件制箭系统已暂时移除。 + +# 杜鹃木功能方块与延展之箭 + +适用:Minecraft 26.2 / NeoForge 26.2.0.93。物品集中在创造模式「原野之风」分页,支持全局搜索。本文命令使用拆分后的模块命名空间。 + +## 获取与配方 + +| 内容 | 物品 ID | 配方 | 数量 | +| --- | --- | --- | --- | +| 杜鹃木告示牌 | `wild_wind_core:azalea_sign` | 前两行各 3 块杜鹃木板,第三行中间 1 根木棍 | 3 | +| 悬挂式杜鹃木告示牌 | `wild_wind_core:azalea_hanging_sign` | 第一行左右各 1 根铁链,后两行各 3 根去皮杜鹃原木 | 6 | +| 杜鹃木展示架 | `wild_wind_core:azalea_shelf` | 第一、三行各 3 根去皮杜鹃原木,中间一行留空 | 6 | +| 延展之箭 | `wild_wind_wilderness:tipped_arrow` | 中央滞留型延展药水,周围 8 支原版箭 | 8 | + +```mcfunction +/give @s wild_wind_core:azalea_sign 3 +/give @s wild_wind_core:azalea_hanging_sign 6 +/give @s wild_wind_core:azalea_shelf 6 +/give @s wild_wind_wilderness:tipped_arrow 64 +/give @s wild_wind_wilderness:tipped_arrow[potion_contents={potion:"wild_wind_wilderness:long_reach"}] 64 +/give @s minecraft:lingering_potion[potion_contents={potion:"wild_wind_wilderness:reach"}] +/give @s minecraft:lingering_potion[potion_contents={potion:"wild_wind_wilderness:long_reach"}] +``` + +两种告示牌最大堆叠 16,展示架与箭最大堆叠 64。方块不添加自然生成。 + +## 告示牌 + +普通告示牌有站立和墙面两种方块,悬挂式有吊顶和墙面两种方块。墙面 ID 分别为 `wild_wind_core:azalea_wall_sign`、`wild_wind_core:azalea_wall_hanging_sign`,由同一对应物品根据放置位置选择。 + +- 继承原版朝向、支撑检查、含水、链条连接与碰撞行为。普通和吊顶告示牌无碰撞,墙面悬挂式仅上方横杆有碰撞。 +- 正反面各四行文字,支持放置时编辑、再次编辑、染料、荧光墨囊、墨囊与蜜脾涂蜡。沿用原版编辑者锁定及服务器文本校验。 +- 沿用原版告示牌方块实体,因此保留非管理员不能设置方块实体数据的保护。 +- 杜鹃木告示牌的世界内文本按需求色表渲染,亮度不随环境照明变化;发光文本使用更亮的颜色和对应描边。其他木种的渲染不变。 +- 两类告示牌硬度与抗爆性均为 1,活塞不可推拉,火焰不会烧毁;燃料时间分别为 200 和 800 刻。 +- 使用现有杜鹃木物品图标,补齐 26.2 方块模型所需的贴图布局与普通告示牌编辑背景。木色取自已有杜鹃木板,链条保留铁色。 + +## 展示架 + +展示架复用原版 `ShelfBlockEntity`,客户端也使用原版展示架物品渲染器。 + +- 正面三槽,每槽一组物品;右键槽位交换主手整组物品。 +- 红石激活后隐藏内部隔板。相邻、同朝向且激活的展示架最多三个连接,右键分别交换快捷栏右侧 3 格、6 格或全部 9 格。 +- 背面比较器输出左槽 1、中槽 2、右槽 4 的和,范围 0–7。其他方向不输出该读数。 +- 支持漏斗等原版容器交互及 NeoForge 物品能力接口。按槽位从左到右处理,每个展示架保有独立库存。 +- 破坏后掉落方块和内容物,存档保存物品。默认物品居中,管理员可改为底部对齐: + +```mcfunction +/data merge block {align_items_to_bottom:1b} +``` + +硬度 2、抗爆性 3;活塞不可推拉;引燃值 30、烧毁值 20,含水时不燃;作为燃料燃烧 300 刻。模型复用原版展示架几何,配套杜鹃木色贴图。 + +## 延展之箭 + +独立物品为 `wild_wind_wilderness:tipped_arrow`,射出的实体为 `wild_wind_wilderness:arrow`。直接给予该物品时默认带普通延展药水成分。 + +| 中央药水 | 箭命中后效果 | +| --- | --- | +| 滞留型延展药水:基础药水时长 3:00 | 延展 I,450 刻(22.5 秒,界面显示约 22 秒) | +| 滞留型延展药水:基础药水时长 8:00 | 延展 I,1200 刻(1 分钟) | + +滞留型药水提示的实际云效果会按原版滞留药水倍率缩短;合成箭按基础药水时长的 1/8 计算,不再额外乘一次滞留倍率。 + +- 弓、弩和发射器均生成专用箭实体,保留原版箭的飞行、伤害、拾取、穿透及武器附魔处理。 +- 无限魔咒不免除延展之箭的消耗。箭插在方块内累计到 600 刻时失去药水成分,拾取获得 `minecraft:arrow`。 +- 原版药箭合成配方在产物是延展/长效延展时返回模组物品;其他药水箭保持原版产物。 +- 两种延展药水加入 `minecraft:tradeable` 药水标签。大师制箭师仍从原版三个选项抽取两个,因此药箭交易出现率为 2/3;该交易再从可交易药水池随机选一种,延展不是固定占 67%。价格为 2 绿宝石 + 5 箭,换 5 支药箭。 +- 村庄英雄的制箭师礼物随机池增加普通延展之箭,保留原有箭与药箭选择,不额外保证赠送一支。 +- 旧存档中的原版 `minecraft:tipped_arrow` 延展箭仍可使用;不会自动批量替换已有物品。 + +## 已执行验证 + +模块拆分后的客户端/服务端数据生成、构建、11 项单元测试、24 组服务端 GameTest 均通过。核心单独安装及完整组合的客户端完成资源加载并自动退出。仍有焦灰草方块及未注册木材模型的既有材质警告。新增五组测试覆盖: + +1. 四种告示牌的有效方块实体、双面文字/颜色/发光/蜡存档、管理员数据限制、掉落、含水属性、硬度、活塞和燃料。 +2. 展示架所有 8 种比较器组合、主手整组交换、库存与对齐存档、漏斗抽取、物品能力、燃料和可燃性。 +3. 红石连接的一至三个展示架实际右键交换 3/6/9 个快捷栏物品,以及第二次交换恢复原物品。 +4. 原版合成路径产出两种延展箭、弓/发射器实体类型、可用弹药标签、无限判定、命中持续时间,以及第 599/600 刻退化边界。 +5. 真实交易数据的价格与大师两选三规则,固定随机种子抽取 2048 次交易和 1024 次英雄礼物,覆盖两种延展交易及原版候选保留。 + +创造分页回归测试同时核对两种延展箭分别出现且不在原版分页重复。以上服务端测试不替代人工检查告示牌编辑界面、荧光文字和展示架三维显示。 diff --git a/docs/BOOK_INSPECTION.md b/docs/BOOK_INSPECTION.md new file mode 100644 index 0000000..61a5b5f --- /dev/null +++ b/docs/BOOK_INSPECTION.md @@ -0,0 +1,88 @@ +# 书与笔属性记录器 + +所属模块:**0 · 原野之风:核心(wild_wind_core)**。Minecraft 26.2 / NeoForge,使用原版书与笔,无需新物品、配方或权限。 + +## 使用 + +1. 手持原版书与笔(`minecraft:writable_book`),主手/副手均可。 +2. 按住潜行键(默认 Shift),右键方块或实体。 +3. 手中的书与笔直接变为原版署名书(`minecraft:written_book`),收到“已生成署名属性书”的提示后,松开潜行,正常右键阅读。 + +书名为 `方块名(方块ID)`,实体使用 `实体类型名(实体ID)`,作者为记录玩家。显示名称随客户端语言翻译,例如 `石头(minecraft:stone)`;实体自定义昵称仍可在正文查看。原版序列化书名最多 32 个字符,超长书名仅截短内部标题,物品显示名称和正文中的完整 ID 保留。 + +一次使用将当前手中的书与笔转换为署名书,不另外赠送一本。属性快照追加到已有笔记之后,保留原页的原始/过滤文本和其他组件,生成第 0 代原本。最多 100 页,剩余页数不足时不转换、不写入,并提示换书。署名书不可继续追加,下一次记录需要另一本书与笔;旁观模式不记录。没有潜行时保留正常交互;记录时不会同时打开容器、交易或触发生物右键行为。 + +可用 `/give @s minecraft:writable_book` 获取测试用书。 + +## 方块字段 + +| 字段 | 取值方式 | +| --- | --- | +| 合适挖掘工具 | 检查原版镐、斧、锹、锄、剪刀和剑的实际工具组件;需正确工具掉落时同时校验掉落资格。基础工具用下界合金代表,只报告工具类型,不表示最低材料等级。无需专门工具时显示徒手,无法采集或未知显示 ×。 | +| 硬度 | 点击处当前方块状态的破坏硬度;`-1` 表示不能常规挖掘。 | +| 爆炸抗性 | 方块提供的基础爆炸抗性;不模拟特定爆炸源、实体或爆炸事件。 | +| 引燃几率/烧毁几率 | NeoForge 各面的蔓延/燃烧整数参数,非固定百分比;各面不同时显示范围,均为零显示 ×。 | +| 熔岩可燃性/是否可燃 | 方块在点击位置的 NeoForge 熔岩引燃/火焰可燃性判定,任一面成立显示“是”。 | +| 窒息生物 | 当前状态的 `isSuffocating` 判定。 | +| 红石导体/压断红石线 | 原版红石导体判定;“压断”指放在线路上方时阻断向上阶梯连接,不指破坏或直接移除红石粉。 | +| 固体方块 | 当前状态的原版 `isSolid` 判定,不等同于所有面都完整碰撞。 | +| 活塞推动行为 | 使用原版活塞可推动检查,包括黑曜石、容器、不可破坏方块、伸出活塞等特殊情况;描述单块自身,未模拟周围黏连结构与 12 格推动上限。 | +| 乐器 | 方块作为音符盒配套方块时的乐器。 | +| 方块 ID | 实际注册 ID。 | +| 烧炼时间 | 作为熔炉燃料的燃烧时长,显示秒和游戏刻;不是原料加工时间。 | +| 硫方怪原型 | 当前服务端原型注册表和物品标签的实际匹配。 | +| 最大堆叠/物品 ID | 对应方块物品的实际值;没有对应物品则显示 ×。 | +| 可再生 | 可扩展数据包标签,已知可再生为“是”,明确不可再生为“否”,未知为 ×。 | +| 烧炼加工时间 | 有匹配熔炉配方时显示其加工时长,无配方为 ×。 | + +另附维度、坐标、完整方块状态、正确工具掉落要求及硫方怪物理参数。布尔属性不成立、属性不适用或无法确认时显示 **×**,不填虚构默认值。零硬度和零抗性仍是有效数值。 + +活塞行为严格使用四种文字: + +- 不可推动,不可拉动 +- 被推动破坏,不可拉动 +- 可推动,不可拉动 +- 可推动,可拉动 + +## 实体字段 + +记录实体 ID、名称、维度和坐标、体积、火焰免疫;生物另有当前/最大生命、护甲、移速、攻击力、击退抗性和氧气。方块专属字段保留并填 ×。 + +掉落物读取自身物品 ID、最大堆叠、燃料和配方信息;普通生物不会把刷怪蛋冒充其物品 ID。硫方怪读取实际吸收物品及所属原型,并附吸收后的基础物理参数。不会读取箱子内容、命令方块命令、实体私有 NBT,也不改变目标。 + +## 硫方怪原型与物理参数 + +沿用需求图中的 13 个分类名称:弹性(橡胶球)、普通(足球)、缓慢平移(药球)、快速平移(高尔夫球)、轻盈(沙滩球)、快速滑行(冰球)、缓慢滑行(冰壶)、缓慢弹性、黏性、高阻力、爆炸、高温、默认。 + +分类从 `minecraft:sulfur_cube_archetype` 注册表匹配,不通过名称猜测材质。数据包增改标签/原型后,新的记录自动使用更新结果。模组物品只有加入对应原型标签才会归入该类,否则为“默认”;未改变硫方怪本身的行为。 + +示例:木板 → 弹性,泥巴 → 普通,铁块 → 缓慢平移,苔藓块 → 快速平移,羊毛 → 轻盈,浮冰 → 快速滑行,蘑菇块 → 缓慢滑行,石头 → 缓慢弹性,蜜脾块 → 黏性,灵魂沙 → 高阻力,TNT → 爆炸,岩浆块 → 高温。当前 26.2 普通冰和蜂蜜块不属于对应原型,不能把截图中的大类当成所有方块的逐项定义。 + +物理页列出击退抗性、弹性、摩擦力修正系数、空气阻力修正系数、水平/垂直击退修正系数、浮力、推动幅度。吸收后的属性使用原版基础属性和匹配原型的实际修改器计算,包括属性上下限;若数据包让同一物品匹配多个原型,按原版顺序叠加。推动幅度按原版玩家推动逻辑计算 `max(0, 1 - 击退抗性)`,没有吸收物品的实体为 0。 + +这些是当前版本/数据包下的吸收参数,不硬编码旧截图数值,也不代表考虑实体药水、玩家接触速度等后的完整运动轨迹。 + +## 扩展可再生名单 + +原版没有通用“可再生”属性,不能从硬度、配方或物品类别准确推断全部内容。因此使用手工维护且可被数据包覆盖的标签: + +```text +data/wild_wind_core/tags/item/inspection/renewable.json +data/wild_wind_core/tags/item/inspection/non_renewable.json +data/wild_wind_core/tags/entity_type/inspection/renewable.json +``` + +例如把模组物品加入可再生名单: + +```json +{ + "replace": false, + "values": ["your_mod:your_item"] +} +``` + +明确不可再生物品标签优先。预置常用木材、羊毛、部分可循环生成方块和常见可繁殖/自然生成生物;未收录不等于不可再生。荒野通过自己的资源包将泥猪加入实体名单,核心无需依赖荒野。 + +## 验证 + +1 项分页单元测试、3 组 GameTest:方块属性与四种活塞行为;真实事件总线上的潜行/副手/旁观/满页行为、署名转换、作者与书名、原始/过滤笔记保留、长标题序列化;以及 12 类硫方怪加默认类的注册表匹配与实际实体属性对照。另在核心单独安装测试中生成署名书,在真实客户端字体加载后检查中文、长 ID 和换行是否超出原版书页宽高。 diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md new file mode 100644 index 0000000..9b8a405 --- /dev/null +++ b/docs/DEVELOPMENT.md @@ -0,0 +1,78 @@ +# 开发指南 + +本项目面向 Minecraft 26.2、NeoForge 26.2.0.93、JDK 25。使用仓库 Gradle Wrapper;首次下载依赖需要网络。 + +## 工程结构 + +| Gradle 项目 | 源码目录 | 用途与依赖 | +| --- | --- | --- | +| `core` | `src/core/` | 模块 0;无需 GeckoLib,不引用两个可选模块 | +| `wilderness` | `src/wilderness/` | 模块 1;依赖 Core 与 GeckoLib 5.5.4 | +| `barren` | `src/barren/` | 模块 2;只依赖 Core | +| `datagen` | `src/datagen/` | 开发用数据生成器;加载全部模块 | +| `verification` | `src/verification/` | 开发用 28 组综合 GameTest;加载全部模块 | +| `smoke` | `src/smoke/` | 开发用安装组合测试;由 `testModules` 选择依赖 | + +发行模块有各自的入口、注册器、Mixin、资源、元数据与 JAR。`src/templates/` 是元数据模板。辅助项目不放入发行目录。 + +核心包 `org.polaris2023.wildwind.core` 包含杜鹃木、窑炉、通用玩法、熔炼和材料;`org.polaris2023.wildwind.structures` 同样位于核心源码中,保留结构兼容命名空间。荒野包为 `org.polaris2023.wildwind.wilderness`,瘠土包为 `org.polaris2023.wildwind.barren`。 + +核心提供创造分页和 `WildWindModules` 命名空间判断;扩展模块通过事件将自己的物品加入分页。荒野的蟹钳挖掘与核心熔炼事件协作,不要求核心反向引用荒野类型。 + +## 构建与开发运行 + +Windows 在仓库根目录执行;其他系统把 `.\gradlew.bat` 改为 `./gradlew`。 + +```powershell +# 资源快照随源码保存,干净检出即可构建 +.\gradlew.bat build collectMods +# 核心 / 核心+荒野 / 核心+瘠土开发客户端 +.\gradlew.bat :core:runClient +.\gradlew.bat :wilderness:runClient +.\gradlew.bat :barren:runClient +# 全部模块开发客户端(加载仅供开发的测试模组) +.\gradlew.bat :smoke:runClient -PtestModules=core,wilderness,barren +``` + +单个模块产物在 `modules/<模块>/build/libs/`,发行集合在 `build/distributions/mods/`。开发世界、日志和测试报告在对应模块 `build/` 下,不纳入版本控制。 + +## 数据生成 + +```powershell +.\gradlew.bat :datagen:runClientData :datagen:runServerData +python scripts/sync_generated_resources.py +.\gradlew.bat build collectMods +``` + +需要 Python 3.9+。生成输出在 `build/generated/datagen/{client,server}/`;同步脚本按注册命名空间分配到三个模块资源目录,并拆分原版/公共标签、数据映射和语言文件。手工资源保留;修改生成器时应提交生成后的快照。删除某项生成内容时,同时删除其已提交的旧快照,避免旧资源残留。 + +模型 Provider 检查三个命名空间的所有已注册方块和物品。未注册的船、焚烬木/灵焰木告示牌等源素材保留,不应为它们新增有效配方。`.bbmodel` 源文件不打入发行 JAR。历史占位材质问题见进度文档。 + +`build` 不会启动游戏数据生成器,避免构建循环;CI 会显式重新生成、同步并检查快照一致性。 + +## 验证 + +```powershell +.\gradlew.bat :core:test :wilderness:test +.\gradlew.bat :verification:runGameTest +.\gradlew.bat :smoke:runGameTest -PtestModules=core +.\gradlew.bat :smoke:runGameTest -PtestModules=core,wilderness +.\gradlew.bat :smoke:runGameTest -PtestModules=core,barren +.\gradlew.bat :smoke:runGameTest -PtestModules=core,wilderness,barren +# 可选本机客户端启动检查:进入标题画面并完成资源检查后自动退出 +.\gradlew.bat :smoke:runClient -PtestModules=core,wilderness,barren -PclientSmoke=true +``` + +安装组合测试加载实际发行模块 JAR,核对依赖、GeckoLib、模块内容归属、创造分页及制箭台移除。各组合使用不同运行目录。综合 GameTest 覆盖结构生成/指令、泥猪、羊毛/剪刀、蜘蛛网、状态效果名单、窑炉、骷髅、耕地、创造分页、杜鹃木功能方块、延展箭及蟹钳联动。 + +若中文 Windows 路径下 JUnit 出现类找不到,而 `.class` 确实存在,可加 `"-Dorg.gradle.jvmargs=-Xmx1G -Dfile.encoding=GBK"` 使 Gradle 参数文件编码匹配本机 Java 启动器;源码始终 UTF-8。 + +## ID 与存档 + +新注册内容使用各自 `wild_wind_*` 命名空间。旧 `ww_hfas:*` 内容没有自动存档映射,不要在唯一旧存档上直接升级。结构的 `ww_structures` 配置、结构 ID 和坐标索引保留,但 NBT 模板内引用旧模组方块时仍需更新。完整分配与安装要求见 [README](../README.md)。 + +自定义部件制箭台和旧替换配置已移除;历史代码可从 Git 历史查阅。已完成的延展药水箭在荒野中保留。 + +提交前运行 `git diff --check`,按改动范围执行上述测试;服务端自动测试不替代游戏内视觉、多人联机和长期存档验收。 + +核心 `inspection/` 包提供书与笔记录器,新增字段时同步维护 `BOOK_INSPECTION.md`。实体交互/署名书转换/书本上限/硫方怪物理参数在 `BookInspectionGameTests` 中验证。`EnchantmentTableGameTests` 使用真实附魔台菜单验证熔炼候选、随机预览和最终工具/书本附魔。 diff --git a/docs/GAMEPLAY.md b/docs/GAMEPLAY.md new file mode 100644 index 0000000..79a8516 --- /dev/null +++ b/docs/GAMEPLAY.md @@ -0,0 +1,188 @@ +# 新增玩法说明 + +适用于 Minecraft 26.2 / NeoForge。羊毛、蜘蛛网、骷髅、耕地、窑炉和熔炼在核心;沉溺、窒息与呼吸规则在荒野,安装组合见 README。 + +## 窑炉 + +`wild_wind_core:kiln` 是同一模组内的功能方块,使用原版熔炉外观,每 100 刻烧炼一件非矿物、非金属装备材料。完整获取方式、漏斗、经验、命名、锁定和村庄生成规则见 [窑炉说明](KILN.md)。 + +## 羊毛拆线 + +任意颜色的 **1 个羊毛 + 1 把剪刀 → 2 个线**,无序配方;支持背包 2×2、工作台 3×3 和自动合成器。 + +- 手动合成后剪刀返还原合成槽;自动合成器会输出线和剪刀,需要自行回收剪刀。 +- 每次合成尝试消耗剪刀 1 点耐久,调用原版耐久规则,因此耐久附魔有概率免除本次损耗。 +- 剪刀的附魔、自定义名称等组件保留;耗尽最后一点耐久时剪刀消失。 +- 每次实际合成都独立判定耐久,连续/Shift 合成同样适用。 +- 配方 ID 与序列化类型均为 `wild_wind_core:wool_to_string`。这是自定义特殊配方,直接放入材料即可合成。 + +## 蜘蛛网挣脱 + +服务器分别记录每个实体对每个正在接触的蜘蛛网的移动时间: + +| 情况 | 所需连续移动时间 | +| --- | --- | +| 通常在网中移动 | 30 游戏刻,正常 20 TPS 下为 1.5 秒 | +| 下坠进入蜘蛛网 | 160 游戏刻,正常 20 TPS 下为 8 秒 | +| 停止位移 | 清零,重新移动后重新计时 | +| 离开该蜘蛛网 | 清零,重新接触后重新计时 | + +下坠/通常移动模式在该次连续接触开始移动时确定。多个蜘蛛网分别计时,达到时限只破坏实际接触且完成计时的蜘蛛网,采用正常方块破坏掉落规则。计时不写入存档。 + +蜘蛛、洞穴蜘蛛、旁观玩家、正在飞行的创造玩家不触发;地面上的创造玩家仍可触发。移动按实际位置变化判断,包括外力推动。 + +## 状态效果 + +这次注册的是两个负面状态效果及图标,没有新增药水物品或酿造配方。可通过指令、数据包或其他模组施加。 + +| 效果 | ID | 行为 | +| --- | --- | --- | +| 沉溺 | `wild_wind_wilderness:sink` | 只对下方沉溺名单生效。接触流体时限制向上位移与向上速度,包括水与熔岩;水平、向下移动仍可进行。更高等级不叠加额外限制。 | +| 窒息 | `wild_wind_wilderness:choke` | 对下方窒息名单中的实体,眼睛浸在水中时加速消耗氧气;I 级 2 倍、II 级 3 倍,依此类推。蝌蚪、美西螈单独在陆地处理。 | + +窒息名单中的青蛙、海龟、骆驼尸壳及铁傀儡也会消耗水下氧气。水下呼吸、潮涌能量、鹦鹉螺之息的药水效果及气泡柱仍提供呼吸保护,创造模式无敌玩家也不受影响;水下呼吸附魔跳过消耗的刻仍保持零消耗。普通名单内实体离水后正常恢复氧气。 + +### 生物适用名单 + +**不会因水下缺氧窒息的原版生物(25 种,重复的溺尸合并)**:鳕鱼、鲑鱼、热带鱼、河豚、鱿鱼、发光鱿鱼、海豚、溺尸、守卫者、远古守卫者、沼骸、史莱姆、岩浆怪、僵尸、僵尸村民、尸壳、骷髅、流浪者、凋灵骷髅、僵尸猪灵、僵尸疣猪兽、幻翼、僵尸马、骷髅马、凋灵。 + +这些生物在水下恢复氧气,优先于窒息效果;即使原先氧气已经耗尽,也不会继续因缺氧受伤。此规则不取消离水干燥伤害、火焰伤害或其他非缺氧伤害,也不移除其他生物原有的水下呼吸能力。 + +**沉溺生效的原版实体(41 种)**:玩家、狐狸、骆驼、骆驼尸壳、鸡、哞菇、牛、驴、马、骡、鹦鹉、猪、兔子、绵羊、嗅探兽、蝌蚪、海龟、流浪商人、山羊、村民、美西螈、猫、青蛙、豹猫、雪傀儡、蜜蜂、熊猫、铁傀儡、羊驼、北极熊、行商羊驼、狼、唤魔者、疣猪兽、猪灵蛮兵、掠夺者、劫掠兽、卫道士、监守者、女巫、猪灵。 + +**窒息在水中生效的原版实体(43 种)**:玩家、狐狸、骆驼、骆驼尸壳、鸡、哞菇、牛、驴、马、骡、鹦鹉、猪、兔子、绵羊、嗅探兽、海龟、流浪商人、山羊、村民、猫、青蛙、豹猫、雪傀儡、蜜蜂、熊猫、铁傀儡、羊驼、北极熊、行商羊驼、狼、唤魔者、疣猪兽、猪灵蛮兵、掠夺者、劫掠兽、卫道士、监守者、女巫、苦力怕、洞穴蜘蛛、蜘蛛、末影人、猪灵。 + +**蝌蚪、美西螈的窒息特例**:不放入 `choke_affected` 标签。代码单独检查 `isInWater()`,在水中不触发;离水后将原版缺氧/干燥消耗提高至 I 级 2 倍、II 级 3 倍。氧气耗尽时继续使用原版伤害与重置规则。美西螈仍保留雨水补水及 NoAI 时不干燥的原版行为。入水后恢复原版补氧。 + +**模组生物**:泥猪 `wild_wind_wilderness:muddy_pig` 继续同时受沉溺和水中窒息影响;泥沼蟹与恐鱼继续免于水下缺氧。 + +两份效果名单均按实体 ID 精确匹配。幻翼现不受这两个效果影响;哞菇、行商羊驼现已加入两份名单。所有其他未列入的实体不受相应效果的移动限制或额外氧气消耗,包括用户列出的不生效实体。窒息不生效不等于获得新的水下呼吸能力,未获免缺氧保护的生物仍可能正常溺水。哞兽 `moobloom` 和冻尸 `frosted_zombie` 当前未注册,也未添加任何必需标签引用。 + +模组水下免缺氧兼容项的来源与当前状态: + +| 生物 | 实体 ID | 状态 | +| --- | --- | --- | +| 泥沼蟹 | `wild_wind_wilderness:mudcrab` | 已随远端 `26.2` 分支合并,当前版本实际注册并通过水下呼吸测试 | +| 恐鱼(Direfish,原食人鱼) | `wild_wind_wilderness:piranha` | 已实际注册并通过水下呼吸测试;更名后沿用原 ID,兼容已有存档 | + +上述两个 ID 以 `required: false` 加入标签。`1.0.1` 已包含泥沼蟹和恐鱼的完整实现;恐鱼、生恐鱼、熟恐鱼、恐鱼刷怪蛋、恐鱼桶及音效字幕均使用新名称,英文为 Direfish。召唤恐鱼使用 `/summon wild_wind_wilderness:piranha`。标签中旧的可选预留项 `wild_wind_core:direfish` 保留兼容,但它不是已注册的实体 ID,也不是召唤别名。安装时需要 GeckoLib 5.5.4 的 Minecraft 26.2 NeoForge 版本。 + +### 用数据包调整名单 + +| 标签 | 数据包文件 | +| --- | --- | +| `wild_wind_wilderness:water_breathing` | `data/wild_wind_wilderness/tags/entity_type/water_breathing.json` | +| `wild_wind_wilderness:sink_affected` | `data/wild_wind_wilderness/tags/entity_type/sink_affected.json` | +| `wild_wind_wilderness:choke_affected` | `data/wild_wind_wilderness/tags/entity_type/choke_affected.json` | + +在数据包中使用同路径 JSON 即可扩展名单。例如,让自定义生物受到沉溺影响: + +```json +{ + "replace": false, + "values": [ + { "id": "your_mod:your_entity", "required": false } + ] +} +``` + +`replace: false` 追加,`replace: true` 替换该标签名单。执行 `/reload` 后生效,标签通过原版数据同步传给客户端。`minecraft:can_breathe_under_water` 标签也引用了免缺氧名单,使原版呼吸判定保持一致。 + +```mcfunction +# 持续 60 秒,默认 I 级 +/effect give @s wild_wind_wilderness:sink 60 +/effect give @s wild_wind_wilderness:choke 60 +# 窒息 II,指令中的等级参数从 0 开始 +/effect give @s wild_wind_wilderness:choke 60 1 +/effect clear @s wild_wind_wilderness:sink +/effect clear @s wild_wind_wilderness:choke +``` + +## 熔炼附魔 + +- ID:`wild_wind_core:melting`,中文「熔炼」,英文「Melting」,最高 I 级。 +- 获取:加入原版 `minecraft:in_enchanting_table` 标签;附魔台可随机给镐、斧、锹、锄等 `#minecraft:enchantable/mining` 工具附加熔炼,也可生成熔炼附魔书。沿用原版书架、等级、青金石和随机抽取规则,不保证每次出现;可使用 15 个有效书架的 30 级选项尝试。附魔权重为 2。 +- 支持 `minecraft:enchantable/mining` 标签中的工具,包括镐、斧、锹、锄与剪刀。 +- 加入原版非宝藏附魔标签,沿用原版相应的附魔台、附魔书交易及随机附魔入口。 +- 手持工具执行 `/enchant @s wild_wind_core:melting 1` 可直接添加。 + +处理顺序如下: + +1. 原版先生成挖掘掉落,包含时运的增量。 +2. 如果工具有精准采集,直接保留所有原掉落,不扣经验。 +3. 查询当前世界的熔炉配方,计算全部可转换掉落需要的经验。 +4. 当前可用经验不足时,整次不转换、不扣经验。 +5. 经验足够时,扣除经验并替换对应掉落;没有熔炉配方的掉落保持原样。 + +**每个输入物品需要 1 点经验值,不是 1 级。** 例如时运产出 3 个粗铁时,需要 3 点经验并得到 3 个铁锭;只有 2 点经验时仍掉落 3 个粗铁。配方产出数量大于 1 时,费用仍按输入数量计算。经验会跨等级准确扣除,采用当前等级与经验条余额,不采用可能因附魔或指令而失真的累计经验计数。 + +熔炼不额外发放熔炉经验。判断发生在方块掉落事件,不会转换玩家背包中已有的物品或生物掉落;没有玩家作为破坏者的自动采矿不触发。精准采集、时运与熔炼可以同时保留在工具上,实际执行仍遵循上述优先级。 + +## 骷髅生成与近战 + +骷髅、流浪者、沼骸、焦骸(`minecraft:skeleton`、`minecraft:stray`、`minecraft:bogged`、`minecraft:parched`)在初始化生成装备时独立进行一次 10% 判定,将主手弓替换为石剑。原版会按武器选择近战/远程 AI;读档和重新加载区块不会重新抽取。凋灵骷髅继续使用原版装备规则。 + +| 生物 | 近战成功命中的效果 | +| --- | --- | +| 骷髅 | 无额外效果 | +| 流浪者 | 缓慢 I,600 游戏刻/30 秒 | +| 沼骸 | 中毒 I,80 游戏刻/4 秒 | +| 焦骸 | 虚弱 I,600 游戏刻/30 秒 | + +仅对成功伤害到的活体目标添加效果;失败攻击不触发。箭矢保留各自的原版效果。 + +测试时可用对应原版刷怪蛋观察生成概率;要直接验证近战,可以生成生物后将其武器换成石剑: + +```mcfunction +/summon minecraft:stray ~ ~ ~ +/item replace entity @e[type=minecraft:stray,sort=nearest,limit=1] weapon.mainhand with minecraft:stone_sword +``` + +在生存模式被命中后检查缓慢 I;替换实体 ID 为 `minecraft:bogged` 或 `minecraft:parched` 可检查另外两种效果。 + +## 耕地保护 + +生物或玩家满足下列任一条件,摔落到耕地时不会使其退化为泥土: + +- 任意已穿戴盔甲槽中有「摔落缓冲」附魔,I 级即可;仅放在手上或背包中无效。 +- 当前具有原版「缓降」效果(`minecraft:slow_falling`)。 + +保护仅阻止摔落踩踏,不取消摔落伤害,不影响缺水、上方被方块阻挡等原版退化规则。可在湿润耕地上分别用普通靴子、摔落缓冲靴子和 `/effect give @s minecraft:slow_falling 60` 对照测试。 + +## 创造模式物品栏 + +所有已注册的模组方块物品与普通物品集中在「原野之风」分页,ID 为 `wild_wind_core:wild_wind`,图标使用杜鹃木板。另收录两种延展药水的普通/喷溅/滞留形态、对应药箭和熔炼 I 附魔书。原版分类中的重复入口已移除,全局搜索仍能找到模组内容。以后加入 `ModBlocks.ITEMS` 或 `ModItems.ITEMS` 的物品会自动收录。 + +## 开发与验证 + +代码分别位于 `src/core/java/org/polaris2023/wildwind/core/` 与 `src/wilderness/java/org/polaris2023/wildwind/wilderness/`: + +| 路径 | 用途 | +| --- | --- | +| `recipe/` | 羊毛配方匹配、输出与剪刀耐久 | +| `mixin/CrafterBlockMixin.java` | 自动合成器的剪刀返还与耐久处理 | +| `event/CobwebBreaking.java` | 服务端蜘蛛网接触与移动计时 | +| `effect/` | 状态效果注册、速度限制与氧气消耗 | +| `mixin/EntityFluidMovementMixin.java` | 在实际位移入口限制流体中上浮 | +| `enchantment/MeltingEnchantment.java` | 熔炼掉落计划、经验计算及扣除 | +| `mixin/AbstractSkeletonMixin.java`、`event/SkeletonBehavior.java` | 生成武器判定与近战命中效果;命中入口位于 `MobMixin` | +| `event/FarmlandProtection.java` | 摔落缓冲/缓降的耕地踩踏保护 | +| `registry/ModCreativeTabs.java` | 独立创造分页及原版重复内容移除 | + +配方、附魔及附魔标签直接保存在 `src/core/resources/data/`;效果图标位于 `src/wilderness/resources/assets/wild_wind_wilderness/textures/mob_effect/`。中英文翻译同步维护源码备用资源与语言数据生成器。 + +在 JDK 25 环境执行: + +```powershell +.\gradlew.bat :datagen:runClientData +.\gradlew.bat :datagen:runServerData +python scripts/sync_generated_resources.py +.\gradlew.bat build collectMods :verification:runGameTest +``` + +`GameplayGameTests` 注册 16 组游戏测试:所有颜色羊毛与槽位顺序、手动连续合成及 Shift 转移、剪刀损坏与耐久附魔、红石驱动的自动合成器、水/熔岩中的沉溺、窒息与呼吸保护、蜘蛛网 30/160 刻边界及豁免、实际实体刻事件、精准采集与时运优先级、经验不足、跨等级扣费及原版方块掉落路径。其中 `FluidEntityRulesGameTests` 核对两份效果名单的完整 ID 集合,逐类验证水下免缺氧名单(含泥沼蟹与恐鱼)、沉溺移动限制,以及所有窒息生效实体的实际水中耗氧、等级倍率和呼吸保护。另有 `land_choke` 测试蝌蚪与美西螈的真实陆地耗氧、伤害阈值、移除效果及返回水中的恢复,并确认共享基类中的鳕鱼不受影响。`UpstreamIntegrationGameTests` 检查泥沼蟹变种、生物桶、恐鱼熔炉配方、延展属性,以及万用蟹钳中的熔炼工具通过真实玩家挖掘路径扣费并产生铁锭。`SkeletonAndFarmlandGameTests` 新增四组测试:固定种子下四类骷髅各 200 次真实生成及武器 AI,三种近战效果的时长/等级和失败攻击,真实摔落路径的耕地保护与剩余伤害,以及模组分页完整性、药水去重与全局搜索。`KilnGameTests` 的三组测试验证窑炉的合成与方块属性、100 刻边界、原料排除、燃料及读档、输出阻塞、湿海绵装水、漏斗流向与取出顺序、经验领取、命名锁定、比较器、破坏掉落,以及六种石匠屋各四个旋转方向的真实结构池放置。另有原来的物品、泥猪与结构测试,加上杜鹃木告示牌、展示架、展示架红石联动、延展箭行为及获取途径五组测试,合计 24 组游戏测试。预留的 `direfish` 项只验证不阻断标签加载,无法执行实体行为测试。 + + +## 杜鹃木功能方块与延展之箭 + +普通/悬挂式告示牌和三槽展示架归核心,独立延展之箭归荒野,全部位于“原野之风”分页。获取命令、配方、红石交换、交易与英雄礼物规则见 [详细说明](AZALEA_AND_REACH_ARROWS.md)。 diff --git a/docs/KILN.md b/docs/KILN.md new file mode 100644 index 0000000..c29165f --- /dev/null +++ b/docs/KILN.md @@ -0,0 +1,82 @@ +# 窑炉(Kiln) + +窑炉是 Minecraft 26.2 / NeoForge 核心模组 `wild_wind_core` 中的功能方块,方块和物品 ID 均为 `wild_wind_core:kiln`。目前复用原版熔炉四向模型、点燃模型、界面贴图、烟雾/火焰粒子和燃烧声,显示名称为「窑炉」。后续可以独立替换模型。 + +## 获取与合成 + +位于创造模式「原野之风」分页,沿用本项目所有模组物品集中分页的设置。最大堆叠为 64。 + +```mcfunction +/give @s wild_wind_core:kiln +/setblock ~ ~ ~ wild_wind_core:kiln[facing=north] +``` + +工作台配方如下,红砖使用 `minecraft:brick`,泥坯使用 `minecraft:packed_mud`: + +| 左 | 中 | 右 | +| --- | --- | --- | +| 空 | 红砖 | 空 | +| 红砖 | 熔炉 | 红砖 | +| 泥坯 | 泥坯 | 泥坯 | + +合成产出 1 个窑炉,获取熔炉后解锁该合成配方。 + +## 烧炼与燃料 + +窑炉读取当前世界的熔炉配方,输出数量、物品组件和经验值沿用该配方,每次固定烧炼 **100 游戏刻**,在 20 TPS 下为 5 秒、每分钟 12 件。砂子、黏土球、圆石、石头、仙人掌、海泡菜、木头、湿海绵及符合条件的其他材料可用。按需求中“矿物、金属工具、武器和盔甲以外”的范围,具有普通熔炉配方的食物也可以烧炼;不会为原本没有配方的物品新增烧炼产物。 + +原料限制由以下规则共同决定: + +- `wild_wind_core:kiln_excluded` 排除标签默认包含公共的矿石、粗金属、锭、粒、宝石标签。 +- 具有高炉配方的原料排除,覆盖原版矿物和金属装备回收。 +- 可损耗耐久的物品若烧炼产物属于 `wild_wind_core:kiln_metal_outputs`(默认锭、粒),也会排除。 + +上方输入槽和顶部漏斗拒绝不符合条件的物品。即使使用指令强行写入不合格原料也不会烧炼或点火。数据包可扩展这两个物品标签;已有配方随世界配方加载/重载生效。 + +使用普通熔炉燃料及燃烧时长,因此一块煤提供 1600 刻燃烧时间,连续烧炼最多 16 件普通单件产物。持续燃烧期间即使缺料或输出堵塞也会消耗剩余燃料。冷炉无有效原料、无空间容纳完整产物时不会消耗新的燃料。移除燃料导致熄火时,未完成进度按原版速度回退;更换不同原料会重新计时。 + +岩浆桶作为燃料会返还铁桶;燃烧期间烧炼湿海绵且燃料槽内存在铁桶时,会得到水桶。燃料容器返还遵循原版及 NeoForge 的 crafting remainder 规则。 + +## 容器、自动化与经验 + +界面上方为烧炼槽、下方为燃料槽、右侧为成品槽,各槽遵循物品自身的最大堆叠限制,支持 Shift 转移。界面使用原版熔炉背景与进度图案,当前不附带配方书。 + +| 漏斗位置 | 行为 | +| --- | --- | +| 上方 | 将可用原料放入烧炼槽 | +| 侧面 | 将燃料放入燃料槽 | +| 下方 | 先取成品,再取燃料槽中的铁桶/水桶 | + +也提供 NeoForge 分面物品传输能力。红石比较器统计全部三个槽位的占用比例,空容器为 0,全部装满为 15。 + +经验按成功完成的原版配方累计并保存。漏斗取出成品保留经验;玩家从成品槽拿取或 Shift 取出时释放此前存储的经验并清空记录。破坏窑炉会掉落内容物并释放剩余经验。物品、燃料时间、进度、配方经验记录、名称及锁定条件均持久化。 + +## 方块属性与采集 + +硬度 3.5,爆炸抗性 3.5。完整实心方块,可使生物窒息、传导红石并压断占位的红石线;不能被活塞推拉。音符盒乐器为底鼓,地图颜色暂用石头色。未燃烧时不发光,燃烧时亮度为 13。 + +用木镐或更好的镐可采集窑炉本体,其他工具不能获得本体;容器内物品和存储经验仍按破坏流程释放。原材料可再生,因此可通过合成持续获得。 + +## 命名与锁定 + +铁砧重命名窑炉物品后再放置,界面显示该名称;用正确工具采集后名称保留。也可用指令修改已放置的方块实体(将坐标替换为目标位置): + +```mcfunction +/data merge block ~ ~ ~ {CustomName:"建筑窑炉"} +/data merge block ~ ~ ~ {lock:{items:"minecraft:brick"}} +/data remove block ~ ~ ~ lock +``` + +上例将锁设为手持红砖才能打开;锁使用当前原版 `lock` 物品谓词格式。旁观模式沿用原版访问规则。锁限制玩家开启界面,不阻止漏斗。 + +## 村庄生成 + +原版沙漠、平原、热带草原、积雪平原(两种)和针叶林共六种石匠屋模板,在通过村庄结构池生成时增加一个窑炉。窑炉朝向随房屋旋转,保留原有切石机和石匠职业工作站。只影响后续新生成的建筑,不扫描或修改存档内已有石匠屋。 + +实现按模板 ID 和已核对的局部位置附加结构处理器,不覆盖原版结构池 JSON 或模板文件。如果数据包在目标位置放了不同方块,会跳过该位置,避免覆盖改造后的箱子或工作站。直接 `/place template` 放置原版模板不会触发结构池附加处理。 + +## 验证与代码入口 + +`KilnGameTests` 提供 `kiln`、`kiln_inventory`、`kiln_villages` 三组服务器游戏测试,涵盖配方、100 刻边界、物品筛选、燃料与保存、容器自动化、经验、锁定、比较器、掉落及六种石匠屋四个旋转方向的结构池放置。客户端界面已编译并注册,尚未进行人工游戏内界面检查。 + +主要实现位于 `block/KilnBlock.java`、`block/entity/KilnBlockEntity.java`、`menu/KilnMenu.java`、`client/KilnScreen.java`、`recipe/KilnRecipes.java`、`worldgen/MasonKilnProcessor.java`。数据生成器维护合成配方、战利品表、挖掘标签、模型引用与中英文名称;源码资源包含无需运行数据生成时的备用文件。 diff --git a/docs/MUDDY_PIG.md b/docs/MUDDY_PIG.md new file mode 100644 index 0000000..a0236ed --- /dev/null +++ b/docs/MUDDY_PIG.md @@ -0,0 +1,58 @@ +# 泥猪 · Muddy Pig + +泥猪属于荒野更新(`wild_wind_wilderness`),使用 Minecraft **26.2**、NeoForge **26.2.0.93**、Java **25**。需要核心与 GeckoLib;新材料和结构生成功能由核心提供。 + +## 资源和动画 + +- 实体 ID:`wild_wind_wilderness:muddy_pig`。 +- 刷怪蛋 ID:`wild_wind_wilderness:muddy_pig_spawn_egg`,复用原版猪刷怪蛋图标。 +- 提供的 `pig_muddy.bbmodel`、`pig_muddy_baby.bbmodel` 原样保留在 `src/wilderness/resources/assets/wild_wind_wilderness/models/entity/pig/`,不会打入 JAR。 +- 成年 64×64、幼年 32×32 PNG 原样保留在 `src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/pig/`。 +- `MuddyPigModel` 将两个模型转换成 Java 模型层。Blockbench 坐标转换为 `(-x, 24-y, z)`,成年身体旋转后重新设置中心;腿部使用关节轴,头饰与头共用动画。 +- 模型继承原版 `PigModel`,不引入 GeckoLib 或额外动画库;声音和 AI 继承原版 `Pig`。成年和幼年使用各自的模型/贴图,不重复缩放幼年模型。 +- 属性为原版猪的 10 点生命和 0.25 移动速度;食物使用 `minecraft:pig_food` 标签。两只泥猪繁殖出泥猪,普通猪不会与泥猪交配。掉落表引用 `minecraft:entities/pig`。 + +修改 `.bbmodel` 后,需同步调整 `client/MuddyPigModel.java` 中的几何与 UV;游戏不会直接读取 Blockbench 文件。 + +## 自然生成与数据包 + +默认在沼泽和红树林沼泽生成,权重 10、每群 2–4 只。权重是群系生物列表内的相对权重,不代表百分比或每区块固定数量。沿用原版动物亮度大于 8 的条件,以及陆地空间、碰撞、距离和生物数量上限检查。 + +以下源码资源可作为数据包覆盖目标,命名空间都是 `wild_wind_wilderness`: + +| 路径(相对 `src/wilderness/resources/`) | 用途 | +| --- | --- | +| `data/wild_wind_wilderness/neoforge/biome_modifier/add_muddy_pig.json` | `neoforge:add_spawns`,调整权重和每群数量 | +| `data/wild_wind_wilderness/tags/worldgen/biome/spawns_muddy_pig.json` | 默认仅包含 `minecraft:swamp`、`minecraft:mangrove_swamp` | +| `data/wild_wind_wilderness/tags/block/muddy_pig_spawnable_on.json` | `#minecraft:animals_spawnable_on`、泥巴、沾泥的红树根 | +| `data/wild_wind_wilderness/loot_table/entities/muddy_pig.json` | 引用原版猪的掉落表 | + +自定义生成群系时,数据包可用 `replace: true` 覆盖群系标签。新增地面仍须满足原版陆地生成的承载与空间检查。更改群系修改器后重启世界/服务器;自然生成仍受原版规则限制,进入群系不保证立即看到泥猪。 + +## 构建和验证 + +在仓库根目录使用 JDK 25 按顺序执行: + +```powershell +.\gradlew.bat :datagen:runClientData +.\gradlew.bat :datagen:runServerData +python scripts/sync_generated_resources.py +.\gradlew.bat build collectMods +.\gradlew.bat :verification:runGameTest +``` + +发行 JAR 位于 `build/distributions/mods/`。泥猪需要客户端和服务端都安装匹配版本的核心、荒野 JAR,以及 GeckoLib 5.5.4(26.2 NeoForge)。泥猪本身仍使用原版模型动画代码。不要将测试模组或 `.bbmodel` 作为游戏模组安装。 + +`build` 包含模型单元测试:检查成年/幼年模型边界和九个原始立方体,比较两种年龄的头部/四腿动画与原版猪。统一 GameTest 模组仅用于 `:verification:runGameTest`,检查实体属性、食物、繁殖、生物蛋、掉落表加载、两个目标群系的实际生成列表,以及草地/泥地/沾泥红树根的生成条件和水/障碍拒绝条件。普通客户端和服务端运行不加载测试模组。 + +手动检查命令: + +```mcfunction +/summon wild_wind_wilderness:muddy_pig ~ ~ ~ +/summon wild_wind_wilderness:muddy_pig ~ ~ ~ {Age:-24000} +/give @s wild_wind_wilderness:muddy_pig_spawn_egg +/locate biome minecraft:swamp +/locate biome minecraft:mangrove_swamp +``` + +观察成年和幼年的纹理、头饰、转头、行走与音效,再到满足亮度和生成空间条件的目标群系观察自然生成。 diff --git a/docs/PROVENANCE.md b/docs/PROVENANCE.md new file mode 100644 index 0000000..807a92c --- /dev/null +++ b/docs/PROVENANCE.md @@ -0,0 +1,37 @@ +# 项目来源与整理范围 + +本仓库于 2026-10-23 从 WildWindModule 的当前工作区建立独立源码快照,包含已提交代码及当时尚未提交的功能实现。 + +- 上游项目:https://github.com/Polari-Stars-MC/WildWindModule +- 上游分支:`26.2` +- 已合并的上游提交:`26ad2da288d7018a1eb39d5bfbf30b2ad0a1520c` +- 整理前本地基线:`39e327eca50f258c645097332d76319c9553e8d4` +- 新增内容:统一结构生成、材料和生物、沉溺/窒息、熔炼、骷髅与耕地规则、窑炉、杜鹃木功能方块、延展之箭及测试。 + +## 保留内容 + +源码、自动测试及测试夹具、游戏资源、Blockbench 模型源文件、Gradle Wrapper、构建配置、GitHub Actions、功能文档、需求说明与原有许可证。泥猪源模型和七种物品图标已经包含在资源目录,不重复复制外部素材目录。 + +## 排除内容 + +本地 IDE 配置、Gradle 缓存、数据生成缓存、构建输出、运行日志、测试世界、JDK 与辅助工具、安装 ZIP/JAR 以及父目录的飞书抓取临时文件。Gradle Wrapper JAR 是构建所需的例外,予以保留。 + +2026-10-23 的独立初始快照没有复制原仓库的 `.git` 历史、凭据或远端配置。2026-10-24 的回传通过双亲合并连接目标仓库历史与独立快照历史,来源基线和兼容性限制见 [上游同步记录](UPSTREAM_SYNC.md)。旧项目保留,可用于查询初始快照之前的本地开发历史。 + +## 上游贡献署名 + +整理前可达提交记录中的作者名称如下(保留原有各源文件署名): + +- Assistant +- CarrotLegend +- Codex +- Mon#Landis +- MonLandis +- baka4n +- cuccuc377-dev +- mdjfnfn +- 刘冬煜 + +## 许可证 + +保留 `LICENSE`、`LICENSE_CODE`、`LICENSE_ASSETS`,未变更许可声明。2026-10-24 将构建元数据中的 `All Rights Reserved` 更正为现有仓库声明的 `GPL-3.0-only AND CC-BY-SA-4.0`,使 JAR 元数据与许可证一致。 diff --git a/docs/STRUCTURES.md b/docs/STRUCTURES.md new file mode 100644 index 0000000..2645a84 --- /dev/null +++ b/docs/STRUCTURES.md @@ -0,0 +1,158 @@ +# 结构生成功能 · 内置于 wild_wind_core + +为 Minecraft **26.2 / NeoForge 26.2.0.93 / Java 25** 添加可配置的世界结构。本功能与七种普通材料归入核心 `wild_wind_core`,无需荒野模块;`ww_structures` 仅作为兼容旧配置与存档的资源命名空间保留。每个结构由一个 JSON 配置与一个原版压缩 NBT 模板组成,无需编写 Java 或手工创建数据包。 + +## 1. 创建第一个结构 + +1. 安装核心 `wild_wind_core-mc26.2-1.0.1.jar`(更新旧版时移除原来的独立 `ww_structures` JAR),创建或打开世界,使配置目录初始化,然后关闭世界/服务器。 +2. 在实例目录中找到 `config/ww_structures/`。专用服务器使用服务器自己的目录;客户端加入服务器时,以服务器配置为准。 +3. 将 `example_ruins.json.disabled` 复制到 `definitions/example_ruins.json`,把 `enabled` 改为 `true`。 +4. 保留随附的 `templates/example_ruins.nbt`,或换成自己的结构方块模板。 +5. 重启并进入允许的群系,探索新区块。世界必须启用原版的结构生成开关。 +6. 用 `/wwstructure search example_ruins` 搜索生成位置;探索该处后用 `/wwstructure locate example_ruins` 查询已生成记录。 + +目录结构: + +```text +config/ww_structures/ +├── definitions/ +│ ├── example_ruins.json +│ └── forest_house.json +├── templates/ +│ ├── example_ruins.nbt +│ └── houses/forest_house.nbt +└── example_ruins.json.disabled +``` + +只读取 `definitions/` 直属目录下以 `.json` 结尾的文件。模板允许子目录;配置中的路径相对于 `templates/`,使用 `/` 分隔,禁止绝对路径和越界链接。 + +**配置和模板在世界启动时读取。修改后必须完整关闭并重新打开世界/重启服务器,`/reload` 不更新这些结构配置。** 同一实例中的存档共用配置,坐标索引则按存档、维度分别保存。 + +## 2. 配置示例 + +```json +{ + "name": "forest_house", + "enabled": true, + "template": "houses/forest_house.nbt", + "biomes": ["minecraft:plains", "#minecraft:is_forest"], + "placement": { + "spacing": 32, + "separation": 8, + "salt": 18372954, + "frequency": 1.0 + }, + "heightmap": "WORLD_SURFACE_WG", + "y_offset": -1, + "rotation": "random", + "include_entities": false, + "conditions": { + "min_y": 60, + "max_y": 160, + "max_terrain_difference": 6, + "avoid_fluids": true, + "ground_blocks": ["minecraft:stone", "#minecraft:dirt", "minecraft:sand"] + } +} +``` + +### 基本字段 + +| 字段 | 默认值 | 含义 | +| --- | --- | --- | +| `name` | 必填 | 唯一名称,匹配 `[a-z0-9_][a-z0-9_-]{0,63}`。生成 ID 为 `ww_structures:`,也是指令使用的名称 | +| `enabled` | `true` | 是否参与自然生成。`false` 仍加载定义和模板,保留已有结构记录 | +| `template` | 必填 | 相对模板文件名,必须是 `.nbt` | +| `biomes` | 必填、非空 | 群系 ID 或以 `#` 开头的群系标签,列表之间为“或”关系 | +| `heightmap` | `WORLD_SURFACE_WG` | 生成高度基准;也支持 `OCEAN_FLOOR_WG`,适合水底结构 | +| `y_offset` | `0` | 在中心采样点第一格空位高度上加的偏移,范围 `-256..256`;地板在模板第 0 层时可设 `-1` 嵌入地面 | +| `rotation` | `random` | `random`、`none`、`clockwise_90`、`clockwise_180`、`counterclockwise_90` | +| `include_entities` | `false` | 是否生成模板保存的实体;方块实体如箱子不受此开关影响 | + +群系遵循原版结构起点检查,不要求整个建筑覆盖范围都位于同一群系。没有额外维度过滤:在使用相同群系的自定义维度中也可能生成。下界和末地可填写对应的群系 ID;地表高度模式不提供下界洞穴底面专用搜索。 + +### 生成管理:`placement` + +| 字段 | 默认值 | 含义 | +| --- | --- | --- | +| `spacing` | `32` | 原版 random-spread 网格间距,单位为区块(每区块 16 格),范围 `1..4096` | +| `separation` | `8` | 网格内候选点的间隔约束,单位为区块;必须 `0 <= separation < spacing` | +| `salt` | 根据名称计算 | `0..2147483647` 的随机盐。不同结构建议使用不同值,减少候选点重合 | +| `frequency` | `1.0` | 候选点通过概率,必须大于 `0` 且不超过 `1`;`0.25` 表示约四分之一候选点继续检查条件 | + +间距不是从玩家位置量起的固定距离,也不保证每个网格必定生成。群系、高度和地形条件可能排除候选点。同一个世界种子、相同配置下的候选位置具有确定性;改变盐值、间距或条件只影响尚未生成的区块。不同结构之间没有额外的互斥或防重叠规则。 + +### 生成条件:`conditions` + +所有条件按“且”组合。模块在旋转后模板覆盖范围的四角与中心共 **5 个点**采样基础地形,不加载相邻区块。 + +| 字段 | 默认值 | 含义 | +| --- | --- | --- | +| `min_y` / `max_y` | `-64` / `320` | 各采样点的第一格空位高度范围,含边界;不是模板最终最低/最高 Y。取值范围 `-2032..2031`,最小值不得超过最大值 | +| `max_terrain_difference` | `8` | 5 点最高与最低高度差的上限,`0..512`。设 `0` 要求采样点等高 | +| `avoid_fluids` | `true` | 排除采样点地面方块或其上方含流体的位置。水底结构通常应设 `false` | +| `ground_blocks` | `[]` | 地面基础方块 ID/标签的允许列表,空数组表示不限;各采样点均须匹配其中之一 | + +采样发生在原版地表装饰之前。**`ground_blocks` 检查噪声生成器的基础地形,而非最终可见草皮、积雪或树叶;例如主世界常为 `minecraft:stone`。** 只填 `minecraft:grass_block` 可能导致完全不生成。5 点采样不能保证整个底面无坑洞或无水;模块也不会自动铺地基、平整山体或防止与其他结构相交。 + +最终模板底部到顶部必须处于当前维度的建筑高度范围内;不满足条件的候选点会被跳过。 + +## 3. 模板制作 + +使用原版结构方块的保存模式制作结构。保存后的压缩 `.nbt` 文件通常在存档的 `generated/<命名空间>/structure/` 下,将它复制到 `config/ww_structures/templates/`,然后在配置中填写文件名。文件必须包含原版 `size`、`blocks` 和 `palette`/`palettes` 数据。 + +- 最大尺寸为 **64 × 256 × 64**(X × Y × Z),压缩文件最大 16 MiB,解压读取预算为 64 MiB。 +- 支持方块状态和方块实体 NBT。箱子的物品/战利品表按模板保存的数据处理;模块不会自动配置战利品。 +- 模板中的空气会替换覆盖位置的方块;需要保留地形的位置请在保存时使用结构空位方块(structure void)。 +- 结构方块本身会被过滤,DATA 标记没有额外的自定义处理逻辑。拼图方块沿用原版模板片段处理,不提供递归拼接建筑功能。 +- `include_entities=true` 时实体按原版模板生成逻辑放置;请自行控制模板实体数量。 +- 不支持直接加载 `.schem`、`.schematic`、`.litematic` 或 `.snbt`。 +- 引用其他模组方块时,客户端和服务器需安装对应模组;移除依赖可能使模板内容无法正确加载。 + +随附 `example_ruins.nbt` 是 7 × 4 × 7 的苔石基座和四根石砖柱,默认不参与自然生成,可用来验证安装。 + +## 4. 指令与坐标 + +这些命令使用与原版 `/locate` 相同的管理员权限(GAMEMASTER,通常为 OP 等级 2)。支持名称补全,结构名可省略 `ww_structures:`。 + +| 指令 | 作用 | +| --- | --- | +| `/wwstructure list` | 列出已加载的配置结构与当前维度有历史记录的结构名称 | +| `/wwstructure locate forest_house` | 查询当前维度已生成记录中,距离执行位置最近的结构 | +| `/wwstructure search forest_house [radius]` | 使用原版搜索算法查找结构起点,默认半径 `16`,允许 `1..64` | +| `/locate structure ww_structures:forest_house` | 也可以使用原版结构定位指令 | + +`locate` 按 **XZ 平面距离**比较,返回结构包围盒底面中心的 X、Y、Z、维度和距离。它查询已保存的坐标索引,不会为搜索额外生成区块。起始区块完成生成并加载后才入库;仅调用 `search` 得到候选位置不会让它自动成为“已生成记录”。跨区块结构的其他部分会随着相邻区块生成而补全。 + +索引随存档按维度保存,服务器重启后仍保留。玩家拆除建筑不会删除历史记录。旧存档的既有结构会在其起始区块重新加载时补记,模块不扫描整个存档的区域文件,因此不会声称能找到从未记录、从未重新加载的所有旧结构。 + +`search` 可以访问未探索区块的结构起点,返回原版定位位置(其 Y 可能为原版的占位高度),不保证整座建筑已经生成。`radius` 是原版结构候选网格的搜索圈数,**不是方块数或普通区块半径**;大间距和复杂条件可能使搜索明显耗时。先用小半径,未找到不等于整个世界不存在该结构。 + +## 5. 修改、停用与错误排查 + +- 停止继续生成:设置 `enabled=false`,保留 JSON 与模板,重启。已有建筑、结构定义和历史索引会保留;原版搜索可能因不再有放置规则而找不到它,已生成记录仍可用 `locate` 查询。 +- 彻底移除/改名:先备份存档。删除定义或修改 `name` 会改变动态注册表 ID,原版可能丢弃旧区块的对应结构元数据;不会替你拆除已有方块。 +- 修改模板:关闭世界后修改再重启。尚未生成的区块使用新模板;跨区块结构若已生成一部分,应保留旧模板以避免接缝。不要在存档的 `generated/ww_structures/structure/` 下保存同名模板,否则原版存档模板优先级可能覆盖配置模板。 +- 已生成区块不补生成。改变配置后请探索新区块或新建测试世界。 +- JSON 拼写错误、参数类型错误、重名、缺失/越界模板、尺寸不合法会带文件名报错并阻止加载,避免悄悄使用错误规则。未知的群系/方块 ID 或缺失标签由原版数据包注册表加载校验,检查服务器日志。 +- 找不到结构时先核对 `enabled`、世界结构生成开关、群系、Y 范围、地形起伏、流体和基础方块限制。新区块生成仍遵循概率,不能保证刚进世界就遇到。 + +## 6. 开发与验证 + +Windows PowerShell: + +```powershell +.\gradlew.bat :core:test :wilderness:test +.\gradlew.bat :verification:runGameTest +.\gradlew.bat build collectMods +``` + +Linux / macOS 将 `.\gradlew.bat` 换成 `./gradlew`。单元测试覆盖配置边界、路径越界、关闭生成时保留定义、资源输出、模板尺寸与坐标索引序列化。统一 GameTest 模组联合加载新物品、泥猪与结构功能,检查配置数据包加载、原版搜索、实际区块生成、模板方块、片段 NBT 保存恢复和指令执行;不会打包进发行 JAR。 + +GameTest 使用 `modules/hfas/build/runs/hfas/gameTest/` 下的专用临时世界;重复运行会重置该测试世界。测试报告为该目录的 `results.xml`。开发运行首次需要下载游戏资源;Gradle 的资源下载工具还可能自动安装 JDK 21,游戏与编译继续使用 JDK 25。 + +测试模组在专用 GameTest 世界启用原版默认关闭的结构生成,并为超平坦预设添加测试结构集合。这些改动只存在于测试资源中。普通超平坦世界若指定了 `structure_overrides`,也需将自己的结构集合加入允许列表;常规默认地形世界没有这项超平坦限制。 + +若中文 Windows 路径下 JUnit 报 `ClassNotFoundException`,但对应 `.class` 已存在,可临时使用 `.\gradlew.bat :core:test :wilderness:test "-Dorg.gradle.jvmargs=-Xmx1G -Dfile.encoding=GBK"`,使 Gradle 参数文件与本机 Java 启动器编码一致。源码仍以 UTF-8 编译;此参数无需写入仓库配置。 + +实际代码在 `src/core/java/org/polaris2023/wildwind/structures/`,直接编入 Core,由 `StructureModule.register` 初始化:`config` 负责配置和不可变资源快照,`worldgen` 注册结构类型/模板片段及坐标索引,`command` 注册查询指令。配置资源通过强制启用的服务器数据包 `ww_structures/config` 接入原版世界生成。 diff --git a/docs/UPSTREAM_MERGE.md b/docs/UPSTREAM_MERGE.md new file mode 100644 index 0000000..a959f77 --- /dev/null +++ b/docs/UPSTREAM_MERGE.md @@ -0,0 +1,48 @@ +# 2026-10-22 远端 26.2 合并记录 + +本文保留当时单模组工程的历史状态和验证结果,不作为当前构建说明。当前三模组结构见 [开发指南](DEVELOPMENT.md),2026-10-24 回传记录见 [上游同步记录](UPSTREAM_SYNC.md)。 + +- 远端:`Polari-Stars-MC/WildWindModule`,分支 `26.2`。 +- 本次重新 fetch 后确认的提交:`26ad2da288d7018a1eb39d5bfbf30b2ad0a1520c`,提交日期 2026-10-17。 +- 默认分支 `master/NeoForge-26.2` 的 `8592680` 是该提交的祖先,已一并包含。 +- 合并分支:`integrate/upstream-26.2-20261022`。 +- 本地功能恢复点:`backup/pre-upstream-20261022`,提交 `9db6d67`。 +- 模组版本从 `1.0.0` 更新为 `1.0.1`;游戏版本仍为 26.2,NeoForge 保留已验证的 26.2.0.93。 + +## 保留与集成 + +保留本地的可配置结构生成/坐标指令、泥猪、七个普通材料、羊毛拆线、蜘蛛网挣脱、沉溺/窒息、熔炼附魔以及生物适用名单。加入远端泥沼蟹、食人鱼、生物桶、万用蟹钳、延展效果与药水、木材资源及配方。 + +物品与实体统一使用 `registry/ModItems.java`、`registry/ModEntities.java`,入口只注册一次;泥猪属性和生成条件加入现有 `EntitiesHandler`。七个材料仍不具有食物组件。结构仍由唯一 `ww_hfas` 模组入口加载。 + +GeckoLib 5.5.4 是必需的外部依赖。开发运行、GameTest 与安装实例均需加载它;游戏测试的依赖配置已继承主代码依赖。 + +## 合并中修复的问题 + +- 合并双方的语言、Mixin、实体标签和资源生成逻辑。 +- 去除远端创造物品栏中对未注册船/告示牌字段的引用。保留源资源,过滤这些内容及未注册盆栽树苗的不可用配方、掉落表、进度、方块状态定义;相关标签使用可选引用。 +- 恢复方块掉落数据生成,并将三个活板门从双层门掉落逻辑改为自身掉落。 +- 泥猪继续使用源码中的原版猪掉落表引用,避免实体数据生成器漏表或在独立生成阶段无法解析原版引用。 +- 水下免缺氧名单继续与原版呼吸标签相连;泥沼蟹和食人鱼实际注册后加入行为测试。 +- 生成资源优先于源码备用 JSON,避免远端静态资源与生成文件重复导致打包失败;数据生成缓存不打包。 +- CI 加入两类数据生成与统一游戏测试。 + +## 验证与限制 + +验证命令: + +```powershell +.\gradlew.bat :hfas:runClientData +.\gradlew.bat :hfas:runServerData +.\gradlew.bat build :hfas:runGameTest +``` + +测试覆盖包括原有结构/泥猪/玩法,以及泥沼蟹变种、生物桶、食人鱼熔炉配方、延展属性和万用蟹钳内部熔炼工具的真实玩家挖掘流程。未进行长时间人工游玩或完整多人联机验证。资料里的 `direfish` 尚无独立实体实现;制箭系统、船、告示牌和盆栽树苗也仍有未完成内容。 + +本次本地验证结果:两类数据生成、完整构建、11 项 JUnit 单元测试与 11 组 GameTest 全部通过;最终游戏测试日志无 ERROR。已检查 JAR 包含本地功能、远端生物、动画资源和翻译,只有一个 `ww_hfas` 模组入口,未包含测试类、建模源文件或数据生成缓存。 + +此次工作为本地合并,没有向 GitHub 推送。 + +## 合并后的名称调整 + +按用户要求,远端食人鱼现统一显示为「恐鱼(Direfish)」,并同步修改生鱼、熟鱼、刷怪蛋、鱼桶和音效字幕的中英文名称。原有实体、物品、配方及资源 ID 保持兼容:恐鱼实体仍为 `ww_hfas:piranha`,召唤指令为 `/summon ww_hfas:piranha`。此前预留的 `ww_hfas:direfish` 不是独立实体或召唤别名。本文上方的食人鱼名称描述合并时的状态。 diff --git a/docs/UPSTREAM_SYNC.md b/docs/UPSTREAM_SYNC.md new file mode 100644 index 0000000..3501cb7 --- /dev/null +++ b/docs/UPSTREAM_SYNC.md @@ -0,0 +1,50 @@ +# 2026-10-24 上游同步记录 + +## 基线与提交历史 + +- 来源:`cuccuc377-dev/WildWindMod`,`main`,`eb12f4fed5472c9be5c51606141fff201b873968`。 +- 目标:`Polari-Stars-MC/WildWindModule`,`master/NeoForge-26.2`,`85926800c060020dd9afbf3c4a8ab90a2540421c`。 +- 集成分支:`sync/wild-wind-modules-20261024`。 +- 目标基线是此前已整合的上游 `26ad2da288d7018a1eb39d5bfbf30b2ad0a1520c` 的祖先;此前本地整合基线为 `39e327eca50f258c645097332d76319c9553e8d4`。 + +来源仓库以独立源码快照开始,没有与目标共享 Git 祖先。此次在目标基线上建立分支,用双亲合并保留目标历史及来源仓库历史;整合树以已包含上游修复的来源版本为基础,再补充同步文档、贡献流程和 CI 加固。没有重写目标分支历史。2026-10-22 的整合范围保留在 [历史记录](UPSTREAM_MERGE.md),快照来源与署名见 [来源说明](PROVENANCE.md)。 + +## 交付范围 + +发行物为三个模组:`wild_wind_core`、`wild_wind_wilderness`、`wild_wind_barren`。荒野与瘠土分别依赖同版本核心;只有荒野需要 GeckoLib。模块归属、功能及命令以 [README](../README.md) 和 [项目进度](../PROGRESS.md) 为准。 + +此次包含此前完成的功能与测试、直接署名的属性书、附魔台熔炼附魔、保持贴图原色的树叶;移除未完成的自定义部件制箭系统,保留已有延展药水箭。保留许可证原文、上游作者与资源素材。 + +## 兼容性与升级 + +这是注册命名空间发生变化的更新,不能视为旧世界的无损替换: + +1. 先备份实例与世界,在新的测试世界验证所需安装组合。 +2. 移除旧 `ww_hfas` 和独立 `ww_structures` 模组文件,安装核心及需要的扩展。客户端、服务端组合一致。 +3. 旧 `ww_hfas:*` 方块、物品、实体没有自动迁移;原有世界内容、NBT 模板和数据包引用需要按新命名空间转换。恐鱼仍使用 `piranha` 路径。 +4. `config/ww_structures/`、结构资源命名空间和坐标索引保留,但模板中的旧方块 ID 仍需更新。 +5. 删除的自定义制箭台没有自动替换恢复逻辑。回退时恢复备份世界及对应旧 JAR,避免继续使用已由新版本保存的世界。 + +## 验证与审查 + +本次提交前执行以下检查;PR 中记录实际结果,GitHub Actions 对合并结果再次执行相同验证: + +```powershell +.\gradlew.bat :datagen:runClientData :datagen:runServerData +python scripts/sync_generated_resources.py +git diff --exit-code -- src/core/resources src/wilderness/resources src/barren/resources +.\gradlew.bat build collectMods :verification:runGameTest +.\gradlew.bat :smoke:runGameTest -PtestModules=core +.\gradlew.bat :smoke:runGameTest -PtestModules=core,wilderness +.\gradlew.bat :smoke:runGameTest -PtestModules=core,barren +.\gradlew.bat :smoke:runGameTest -PtestModules=core,wilderness,barren +git diff --check +``` + +发行集合仅包含三个模组 JAR,不包含测试模组、IDE 设置、本地工具、构建缓存或测试世界。CI 使用只读令牌权限、固定 Actions 提交、超时及重复任务取消,并保留测试报告。 + +2026-10-24 本地验证:两类数据生成与快照一致性检查、完整构建、12 项 JUnit、28 项综合 GameTest 和四种安装组合测试均通过;三个发行 JAR 的许可元数据与资源排除检查通过。 + +服务端与数据生成自动检查不等于人工视觉验收、长期游玩或多人兼容性验证。目标分支要求 PR 与至少一位审核者批准;必须等待审查,不绕过保护规则。 + +已有 PR #33(`26.2-fix` → `master/NeoForge-26.2`)尚未合并,其头提交 `63b06e313b4dcff28b53593a0e99ae7e1335bdf0` 比本次已整合的 `26ad2da` 多 8 个提交,涉及木材生成器整理、标签/配方及恐鱼音效修复。本次不将该待审分支视为已合并内容,也不修改它;审查者应协调两个 PR 的集成顺序,并重新验证重叠部分。 diff --git "a/docs/specifications/\345\273\266\345\261\225\344\271\213\347\256\255(Tipped Arrow).md" "b/docs/specifications/\345\273\266\345\261\225\344\271\213\347\256\255(Tipped Arrow).md" new file mode 100644 index 0000000..ac2ad0e --- /dev/null +++ "b/docs/specifications/\345\273\266\345\261\225\344\271\213\347\256\255(Tipped Arrow).md" @@ -0,0 +1,64 @@ +# 延展之箭\(Tipped Arrow\) + +**具有药水效果的箭变种,可以对击中的生物施加延展状态效果\.** + +**物品创造标签页:战斗物品** + +**最大堆叠:64** + +**可再生:是** + +**物品ID:wwhfas:tipped\_arrow** + +**实体ID:wwhfas:arrow** + +**获取** +**———————————————————** + +**交易:** + +**■交易目标:大师级制箭师村民** + +**▪概率:67%概率** + +**▪收购物品:绿宝石x2,箭x5** + +**▪出售物品:延展之箭x5** + +**药水箭的交易选项会从除水瓶、粗制的药水、平凡的药水和浓稠的药水制成的药箭外的所有生存模式可获取的药箭中随机选择,包括所有的改性变种\.其中也包含延展之箭\.** + +**礼物:** + +**制箭师会向带有村庄英雄效果的玩家投掷延展之箭\.** + +**当玩家在村庄获得村庄英雄效果后,制箭师会从箭、抗火之箭、伤害之箭、治疗之箭、隐身之箭、跳跃之箭、夜视之箭、剧毒之箭、再生之箭、迟缓之箭、力量之箭、迅捷之箭、水肺之箭、虚弱之箭、延展之箭中随机选取投掷给予玩家\.其中也包含延展之箭\.** + +**合成:** + +**■B** + +**▪第一行:箭,箭,箭\.** + +**▪第二行:箭,A,箭\.** + +**▪第三行:箭,箭,箭\.** + +**当A为滞留型延展药水\(03:00\)时,B为延展之箭\(00:22\)x8\.** + +**当A为滞留型延展药水\(08:00\)时,B为延展之箭\(01:00\)x8\.** + +**用途** +**———————————————————** + +**具有无限魔咒的弓在使用延展之箭射击时,药箭会被正常消耗\.** + +**行为** +**———————————————————** + +**延展之箭具有与箭相同的行为。** + +**延展之箭在卡进方块30秒后,会集中散发一次药水粒子效果,随后丢失所有的药水效果数据\.此时再次捡起只会获得普通的箭\.** + +**造成状态效果:** + +**延展之箭在命中生物时会对其施加延展状态效果\.** diff --git "a/docs/specifications/\346\202\254\346\214\202\345\274\217\346\235\234\351\271\203\346\234\250\345\221\212\347\244\272\347\211\214(Azalea Hanging Sign).md" "b/docs/specifications/\346\202\254\346\214\202\345\274\217\346\235\234\351\271\203\346\234\250\345\221\212\347\244\272\347\211\214(Azalea Hanging Sign).md" new file mode 100644 index 0000000..3fe3a4e --- /dev/null +++ "b/docs/specifications/\346\202\254\346\214\202\345\274\217\346\235\234\351\271\203\346\234\250\345\221\212\347\244\272\347\211\214(Azalea Hanging Sign).md" @@ -0,0 +1,103 @@ +# 悬挂式杜鹃木告示牌\(Azalea Hanging Sign\) + +**一种可以显示文本的方块\.** + +**合适挖掘工具:斧** + +**硬度:1** + +**爆炸抗性:1** + +**引燃几率:0** + +**烧毁几率:0** + +**熔岩可燃性:是** + +**窒息生物:否** + +**红石导体:否** +**压断红石线:否** + +**固体方块:是** + +**活塞推动行为:不可推动,不可拉动** + +**乐器:贝斯** + +**地图基色:暂未设定** + +**方块ID:azalea\_hanging\_sign** + +**物品创造标签页:功能方块** + +**烧炼时间:800游戏刻\(40秒,4个物品\)** + +**最大堆叠:16** + +**可再生:是** + +**物品ID:azalea\_hanging\_sign** + +**生成** +**———————————————————** +**悬挂式杜鹃木告示牌不会生成在世界中\.** + +**获取** +**———————————————————** + +**合成:** +**■悬挂式杜鹃木告示牌x6:** + +**▪第一行:铁链,空位,铁链** + +**▪第二行:去皮杜鹃原木,去皮杜鹃原木,去皮杜鹃原木** + +**▪第三行:去皮杜鹃原木,去皮杜鹃原木,去皮杜鹃原木** + +**破坏** +**———————————————————** + +**挖掘悬挂式杜鹃木告示牌的合适工具是斧\.** + +**悬挂式杜鹃木告示牌被破坏后会掉落自身\.** + +**用途** +**———————————————————** + +**放置:** + +**悬挂式杜鹃木告示牌必须放置在****中心完整****的方块底面或完整的方块侧面,或者其他悬挂式告示牌的底部或侧面\.** + +**放置在方块侧面的悬挂式杜鹃木告示牌有4个朝向,带有一根横杆,杆与牌之间由两条平行铁链相连\.** + +**放置在方块底面的悬挂式杜鹃木告示牌,其铁链直接固定于该面\.若该面完整,则两条铁链平行,玩家能以4个朝向放置此悬挂式杜鹃木告示牌,若该面仅中心完整,或玩家在潜行状态下放置,则两条铁链相交于面中心,玩家能以16个朝向放置此悬挂式杜鹃木告示牌\.** + +**放置在方块底面的悬挂式杜鹃木告示牌,会在其附着的方块移动或被移除的情况下破坏并掉落自身\.** + +**文本:** + +**悬挂式杜鹃木告示牌的正面和背面都可以显示文本,一个面最多可输入4行文本\.** + +**对有文字的悬挂式杜鹃木告示牌使用****染料****可以改变文本颜色\.对其使用****荧光墨囊****可以提高文本亮度,使用****墨囊****可以移除发亮效果\.** + +**对着悬挂式杜鹃木告示牌使用****蜜脾****可以涂蜡,涂蜡后的悬挂式杜鹃木告示牌不再能被编辑文字、染色或改变发亮效果,若要修改则需破坏后重新放置杜鹃木悬挂式告示牌\.** + +**交互:** + +**放在方块侧面的悬挂式杜鹃木告示牌有****碰撞箱****,但仅包含上方的横杆,放置后可以不依赖于该方块侧面而独立存在\.放在方块底面的悬挂式杜鹃木告示牌没有碰撞箱\.** + +**在活塞无法推动悬挂式杜鹃木告示牌\.悬挂式杜鹃木告示牌被活塞拉动时不会有反应\(除非它附在伸出的活塞头表面\)\.** + +**水****和****熔岩****会绕开悬挂式杜鹃木告示牌流动\.悬挂式杜鹃木告示牌不会被****火****燃尽\.** + +**燃料:** +**悬挂式杜鹃木告示牌可以作为熔炉、高炉和烟熏炉的燃料,每个悬挂式杜鹃木告示牌可以烧炼4个物品\.** + +**安全保护:** + +**悬挂式杜鹃木告示牌属于“仅管理员可设置数据”的方块\.** + +**非管理员玩家对悬挂式杜鹃木告示牌按下Ctrl\+选取方块时不会复制方块实体数据,放置物品栏中已有的带有方块实体数据的悬挂式杜鹃木告示牌也不会将数据实际加载\.** + +**管理员玩家的物品栏中带有方块实体数据的悬挂式杜鹃木告示牌的物品****提示框****中会显示警告信息\.** diff --git "a/docs/specifications/\346\235\234\351\271\203\346\234\250\345\221\212\347\244\272\347\211\214(Azalea Sign).md" "b/docs/specifications/\346\235\234\351\271\203\346\234\250\345\221\212\347\244\272\347\211\214(Azalea Sign).md" new file mode 100644 index 0000000..ac3bafc --- /dev/null +++ "b/docs/specifications/\346\235\234\351\271\203\346\234\250\345\221\212\347\244\272\347\211\214(Azalea Sign).md" @@ -0,0 +1,142 @@ +# 杜鹃木告示牌\(Azalea Sign\) + +**一种可以显示文本的方块\.** + +**合适挖掘工具:斧** + +**硬度:1** + +**爆炸抗性:1** + +**引燃几率:0** + +**烧毁几率:0** + +**熔岩可燃性:是** + +**窒息生物:否** + +**红石导体:否** +**压断红石线:否** + +**固体方块:是** + +**活塞推动行为:不可推动,不可拉动** + +**乐器:贝斯** + +**地图基色:暂未设定** + +**方块ID:azalea\_sign** + +**物品创造标签页:功能方块** + +**烧炼时间:200游戏刻\(10秒,1个物品\)** + +**最大堆叠:16** + +**可再生:是** + +**物品ID:azalea\_sign** + +**生成** +**———————————————————** +**杜鹃木告示牌不会生成在世界中\.** + +**获取** +**———————————————————** + +**合成:** +**■杜鹃木告示牌x3:** + +**▪第一行:杜鹃木板,杜鹃木板,杜鹃木板** + +**▪第二行:杜鹃木板,杜鹃木板,杜鹃木板** + +**▪第三行:空位,木棍,空位** + +**破坏** +**———————————————————** + +**挖掘杜鹃木告示牌的合适工具是斧\.** + +**杜鹃木告示牌被破坏后会掉落自身\.** + +**用途** +**———————————————————** + +**放置:** + +**杜鹃木告示牌必须放置在固体方块(包括栅栏、玻璃、其他告示牌)的顶部或侧面。放置在方块顶部的杜鹃木告示牌会竖立在一根短标杆上,朝向放置此杜鹃木告示牌的玩家,总共可朝向16个不同的方向\.放置在方块侧面的杜鹃木告示牌会附在该方块的侧表面,当该方块侧面不完整时则飘浮在其所在格的侧表面\.** + +**杜鹃木告示牌会在其附着的方块移动或被移除的情况下被破坏并掉落自身\.** + +**文本:** + +**杜鹃木告示牌的正面和背面都可以显示文本,一个面最多可输入4行文本。** + +**放置杜鹃木告示牌时会自动打开杜鹃木告示牌正面的文本编辑界面。如果放置的杜鹃木告示牌已经有文本了\(如通过物品数据添加\),那么杜鹃木告示牌被放置后不会出现文本输入界面\.** + +**输入时可使用鼠标或方向键移动光标位置。点击“完成”或者Esc按钮可以关闭文本输入界面\.** + +**当编辑窗口关闭后,对着已放置的杜鹃木告示牌按下使用键可重新打开编辑窗口,以编辑其正面或背面的文本\.** + +**对着杜鹃木告示牌使用蜜脾可以涂蜡,涂蜡后的杜鹃木告示牌不再能被编辑文字、染色或改变发亮效果,若要修改则需破坏后重新放置杜鹃木告示牌\.** + +**对有文字的杜鹃木告示牌使用染料可以改变文本颜色\.** + +**■杜鹃木告示牌上显示的文字不受周围亮度影响\.对杜鹃木告示牌使用荧光墨囊可以提高文本亮度,使用墨囊可以移除发亮效果\.杜鹃木告示牌文字被增亮后会出现外边框,边框颜色随文字颜色而定:** + +**▪文字颜色为黑色时,十六进制颜色码为\#000000,边框十六进制颜色码为\#F0EBCC,** + +**▪文字颜色为红色时,十六进制颜色码为\#FF0000,边框十六进制颜色码为\#660000,** + +**▪文字颜色为绿色时,十六进制颜色码为\#00FF00,边框十六进制颜色码为\#006600,** + +**▪文字颜色为棕色时,十六进制颜色码为\#8B4513,边框十六进制颜色码为\#371B07,** + +**▪文字颜色为蓝色时,十六进制颜色码为\#0000FF,边框十六进制颜色码为\#000066,** + +**▪文字颜色为紫色时,十六进制颜色码为\#A020F0,边框十六进制颜色码为\#400C60,** + +**▪文字颜色为青色时,十六进制颜色码为\#00FFFF,边框十六进制颜色码为\#006666,** + +**▪文字颜色为浅灰色时,十六进制颜色码为\#D3D3D3,边框十六进制颜色码为\#545454,** + +**▪文字颜色为灰色时,十六进制颜色码为\#808080,边框十六进制颜色码为\#333333,** + +**▪文字颜色为粉色时,十六进制颜色码为\#FF69B4,边框十六进制颜色码为\#662A48,** + +**▪文字颜色为黄绿色时,十六进制颜色码为\#BFFF00,边框十六进制颜色码为\#4C6600,** + +**▪文字颜色为黄色时,十六进制颜色码为\#FFFF00,边框十六进制颜色码为\#666600,** + +**▪文字颜色为浅蓝色时,十六进制颜色码为\#9AC0CD,边框十六进制颜色码为\#3D4C52,** + +**▪文字颜色为品红色时,十六进制颜色码为\#FF00FF,边框十六进制颜色码为\#660066,** + +**▪文字颜色为橙色时,十六进制颜色码为\#FF681F,边框十六进制颜色码为\#66290C,** + +**▪文字颜色为白色时,十六进制颜色码为\#FFFFFF,边框十六进制颜色码为\#666666,** + +**杜鹃木告示牌文本可以包含****格式化代码****\.杜鹃木告示牌文本可使用****文本组件****\.** + +**如果有其他玩家正在编辑杜鹃木告示牌内容,则不能与该杜鹃木告示牌进行任何交互\.** + +**交互:** + +**杜鹃木告示牌没有碰撞箱,因此****实体****可以穿过杜鹃木告示牌\.其他方块\(包括其他告示牌\)可以被放在杜鹃木告示牌的任何一角\.** + +**活塞无法推动杜鹃木告示牌\.杜鹃木告示牌被活塞拉动时不会有反应\(除非杜鹃木告示牌附在伸出的活塞头表面\)\.** + +**水****和****熔岩****会绕开杜鹃木告示牌流动\.杜鹃木告示牌不会被****火****燃尽\.** + +**燃料:** +**杜鹃木告示牌可以作为熔炉、高炉和烟熏炉的燃料,每个杜鹃木告示牌可以烧炼1个物品\.** + +**安全保护:** +**杜鹃木告示牌属于“仅管理员可设置数据”的方块\.** + +**非管理员玩家对杜鹃木告示牌按下Ctrl\+选取方块时不会复制方块实体数据,放置物品栏中已有的带有方块实体数据的杜鹃木告示牌也不会将数据实际加载\.** + +**管理员玩家的物品栏中如果携带着有方块实体数据的杜鹃木告示牌,物品****提示框****中会显示警告信息\.** diff --git "a/docs/specifications/\346\235\234\351\271\203\346\234\250\345\261\225\347\244\272\346\236\266(Azalea Shelf).md" "b/docs/specifications/\346\235\234\351\271\203\346\234\250\345\261\225\347\244\272\346\236\266(Azalea Shelf).md" new file mode 100644 index 0000000..35a9ab5 --- /dev/null +++ "b/docs/specifications/\346\235\234\351\271\203\346\234\250\345\261\225\347\244\272\346\236\266(Azalea Shelf).md" @@ -0,0 +1,116 @@ +# 杜鹃木展示架\(Azalea Shelf\) + +**一种可用于存放和展示物品的功能方块\.** + +**合适挖掘工具:斧** + +**硬度:2** + +**爆炸抗性:3** + +**引燃几率:30** + +**烧毁几率:20** + +**熔岩可燃性:是** + +**窒息生物:否** + +**红石导体:否** +**压断红石线:否** + +**固体方块:是** + +**活塞推动行为:不可推动,不可拉动** + +**乐器:贝斯** + +**地图基色:暂未设定** + +**方块ID:azalea\_shelf** + +**物品创造标签页:功能方块** + +**烧炼时间:300游戏刻\(15秒,1\.5个物品\)** + +**最大堆叠:64** + +**可再生:是** + +**物品ID:azalea\_shelf** + +**生成** +**———————————————————** +**杜鹃木展示架不会生成在世界中\.** + +**获取** +**———————————————————** + +**合成:** +**■杜鹃木展示架x6:** + +**▪第一行:去皮杜鹃原木,去皮杜鹃原木,去皮杜鹃原木** + +**▪第二行:空位,空位,空位** + +**▪第三行:去皮杜鹃原木,去皮杜鹃原木,去皮杜鹃原木** + +**破坏** +**———————————————————** + +**挖掘杜鹃木展示架的合适工具是斧\.** + +**杜鹃木展示架被破坏后会掉落自身和内容物\.** + +**用途** +**———————————————————** + +**存放物品:** + +**杜鹃木展示架正面有3个槽位,可存放最多3组物品\.与任意槽位交互时,玩家的主手物品会与所交互槽位的物品交换\.** + +**类似于物品展示框,杜鹃木展示架会在正面展示其包含的所有物品\.但与之不同的是其内部物品不可旋转\.** + +**方块实体数据align\_items\_to\_bottom控制了杜鹃木展示架槽位中展示物品的位置\.其值为false\(默认值\)时,物品位置居中;其值为true时,物品置于底部隔板上方\.无法通过命令以外的其他方式修改其值\.** + +**激活:** + +**■杜鹃木展示架可以被红石信号激活,此时其正面纹理会随之改变,槽位之间的“隔板”会消失\.激活的杜鹃木展示架可以与其他激活的展示架相互连接,最多可以连接3个,相互连接的展示架连接处的“隔板”会消失\.此时,杜鹃木展示架的行为如下:** + +**▪与单个杜鹃木展示架交互时,其包含的所有物品会与玩家快捷栏右起3个物品交换\.** + +**▪与两个相连接的展示架交互时,其包含的所有物品会与玩家快捷栏右起6个物品交换\.** + +**▪与三个相连接的展示架交互时,其包含的所有物品会与玩家快捷栏的所有物品交换\.** + +**红石比较器:** + +**■红石比较器可以从背面检测展示架内的物品排布,并输出相应强度的红石信号,范围为0–7\.计算方式类似于二进制:** + +**▪所有槽位均无物品时,信号强度为0\.** + +**▪左、中、右槽位有物品时,信号强度分别增加1、2、4\.** + +**■若以○表示该槽位有物品,×表示该槽位无物品:** + +**▪槽位顺序为×××时,信号强度增加0,** + +**▪槽位顺序为○××时,信号强度增加1,** + +**▪槽位顺序为×○×时,信号强度增加2,** + +**▪槽位顺序为○○×时,信号强度增加3,** + +**▪槽位顺序为××○时,信号强度增加4,** + +**▪槽位顺序为○×○时,信号强度增加5,** + +**▪槽位顺序为×○○时,信号强度增加6,** + +**▪槽位顺序为○○○时,信号强度增加7,** + +**容器交互:** +**漏斗****可以为杜鹃木展示架放入或取出物品,****投掷器****和****合成器****可以为杜鹃木展示架放入物品,****漏斗矿车****可以为杜鹃木展示架取出物品\.无论位于杜鹃木展示架的哪一侧,它们总是会与满足条件的左起第一个槽位交互,即以从左到右的顺序放入或取出物品\.多个展示架相连接时,这些方块只会与其直接连接的展示架交互,而无法与连接的其他展示架交互。** + +**燃料:** +**杜鹃木展示架可以作为熔炉、高炉和烟熏炉的燃料,每个杜鹃木展示架可以烧炼1\.5个物品\.** diff --git "a/docs/specifications/\347\252\221\347\202\211(Kiln).md" "b/docs/specifications/\347\252\221\347\202\211(Kiln).md" new file mode 100644 index 0000000..0e5c604 --- /dev/null +++ "b/docs/specifications/\347\252\221\347\202\211(Kiln).md" @@ -0,0 +1,90 @@ +# 窑炉\(Kiln\) + +**专用于烧炼各类建筑材料和染料等杂物的****熔炉****变种\.** + +**合适挖掘工具:镐** + +**硬度:3\.5** + +**爆炸抗性:3\.5** + +**窒息生物:是** + +**红石导体:是** +**压断红石线:是** + +**固体方块:是** + +**活塞推动行为:不可推动,不可拉动** + +**乐器:底鼓** + +**地图基色:暂未设定** + +**亮度:13\(燃料燃烧时\)** + +**方块ID:kiln** + +**物品创造标签页:功能方块** + +**最大堆叠:64** + +**可再生:是** + +**物品ID:kiln** + +**生成** +**———————————————————** +**自然生成:** + +**窑炉会生成在****村庄****的石匠屋中\.** + +**获取** +**———————————————————** + +**合成:** +**■窑炉:** + +**▪第一行:空位,红砖,空位** + +**▪第二行:红砖,熔炉,红砖** + +**▪第三行:泥坯,泥坯,泥坯** + +**破坏** +**———————————————————** + +**挖掘窑炉的合适工具是镐。窑炉需要木镐或品质更好的镐来挖掘,否则挖掘时间将延长且不会掉落\.** + +**窑炉被破坏后会掉落自身、内容物和储存的经验值\.** + +**用途** +**———————————————————** + +**窑炉不能被****活塞****推动\.** + +**烧炼:** +**窑炉只能****烧炼****矿物、金属工具、武器和盔甲以外的物品\.速度为每100****游戏刻****\(5秒\)烧炼一个物品,即每分钟烧炼12个物品,是****熔炉****的2倍\.** + +**使用窑炉可以打开它的界面\.下方的槽位为"燃料槽",用于放置燃料\(最多1组\),上方的槽位为“烧炼槽”,用于放置烧炼物\(最多1组\),右侧的槽位为"成品槽",烧炼成品会存放于此\(最多1组\)\.** + +**连接到窑炉上面的****漏斗****会向烧炼槽中添加烧炼物,连接到窑炉侧面的漏斗会向燃料槽中添加燃料,窑炉下面的漏斗会取走成品槽中的成品和燃料槽中的****铁桶****,如果铁桶与成品槽的成品同时存在会优先吸取成品\.** + +**烧炼产生的经验会存储在窑炉中,当玩家取出成品槽中的成品或窑炉被破坏时一并给予玩家\.** + +**燃烧中的窑炉会生成烟雾和火焰****粒子****\.** + +**红石比较器:** +**红石比较器****可检测窑炉的内容物占空比,烧炼槽、燃料槽和成品槽都会被统计\.** + +**光源:** + +**燃烧中的窑炉会发出****亮度****等级为13级的光\.** + +**自定义名称:** + +**窑炉界面的标题默认为“窑炉”,可以在未放置之前使用铁砧重命名来进行更改,也可以通过使用****`/`****`data`****命令修改窑炉的****`CustomName`****标签进行更改\.** + +**锁定:** + +**窑炉可以被****`lock`****标签上锁\.如果窑炉的该标签不是空白的,那么这个窑炉必须使用符合该标签表示的物品谓词的物品打开\.** diff --git a/gradle.properties b/gradle.properties index a41b60d..ab20440 100644 --- a/gradle.properties +++ b/gradle.properties @@ -14,19 +14,15 @@ minecraftVersion=26.2 # as they do not follow standard versioning conventions. minecraftVersionRange=[26.2] # The Neo version must agree with the Minecraft version to get a valid artifact -neoVersion=26.2.0.75 +neoVersion=26.2.0.93 ## Mod Properties -# The unique mod identifier for the mod. Must be lowercase in English locale. Must fit the regex [a-z][a-z0-9_]{1,63} -# Must match the String constant located in the main mod class annotated with @Mod. -modId=wild_wind -# The human-readable display name for the mod. -modName=Wild Wind -# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default. -modLicense=All Rights Reserved +# Module IDs and titles are defined per project in build.gradle.kts. +# Matches the existing code and asset licenses in LICENSE (no license change). +modLicense=GPL-3.0-only AND CC-BY-SA-4.0 # The mod version. See https://semver.org/ -modVersion=1.0.0 +modVersion=1.0.1 # The group ID for the mod. It is only important when publishing as an artifact to a Maven repository. # This should match the base package used for the mod sources. # See https://maven.apache.org/guides/mini/guide-naming-conventions.html diff --git a/gradlew b/gradlew old mode 100644 new mode 100755 diff --git a/scripts/sync_generated_resources.py b/scripts/sync_generated_resources.py new file mode 100644 index 0000000..f83eddf --- /dev/null +++ b/scripts/sync_generated_resources.py @@ -0,0 +1,70 @@ +"""Copy datagen output into its owning release module; split shared tags/maps/languages. + +Run after :datagen:runClientData and :datagen:runServerData. Hand-authored +resources not emitted by datagen are preserved. No local paths or dependencies. +""" +import json +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +MODULES = ("core", "wilderness", "barren") + + +def owner(value): + for module in MODULES: + if "wild_wind_" + module in value: + return module + # Vanilla potion translation keys and sound subtitles have no mod namespace. + if any(token in value for token in ("reach", "piranha", "mudcrab")): + return "wilderness" + return "core" + + +def save(module, relative, value, merge=False): + path = ROOT / "src" / module / "resources" / relative + path.parent.mkdir(parents=True, exist_ok=True) + if merge and path.exists(): + value = json.loads(path.read_text(encoding="utf-8")) | value + path.write_text(json.dumps(value, ensure_ascii=False, indent=2) + "\n", encoding="utf-8") + + +def main(): + count = 0 + for side in ("client", "server"): + directory = ROOT / "build/generated/datagen" / side + if not directory.is_dir(): + raise SystemExit(f"Missing {directory}; run both datagen tasks first.") + for path in sorted(directory.rglob("*.json")): + relative = path.relative_to(directory) + if relative.parts[0] not in ("assets", "data"): + continue + data = json.loads(path.read_text(encoding="utf-8")) + if "lang" in relative.parts: + groups = {module: {} for module in MODULES} + for key, value in data.items(): + if "fletching_table" not in key and "arrow_component" not in key: + groups[owner(key)][key] = value + for module, entries in groups.items(): + save(module, f"assets/wild_wind_{module}/lang/{path.name}", entries, merge=True) + elif relative.parts[1] in ("minecraft", "neoforge", "c") and ("tags" in relative.parts or "data_maps" in relative.parts): + maps = "data_maps" in relative.parts + groups = {module: {} if maps else [] for module in MODULES} + if maps: + for key, value in data["values"].items(): + groups[owner(key)][key] = value + else: + for value in data["values"]: + groups[owner(value if isinstance(value, str) else value["id"])].append(value) + for module, values in groups.items(): + if values: + save(module, relative, data | {"values": values}) + else: + (ROOT / "src" / module / "resources" / relative).unlink(missing_ok=True) + else: + save(owner(str(relative)), relative, data) + count += 1 + print(f"Synced {count} generated resources into three release modules.") + + +if __name__ == "__main__": + main() diff --git a/settings.gradle.kts b/settings.gradle.kts index 247830d..4f0ce04 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -8,14 +8,14 @@ plugins { id("org.gradle.toolchains.foojay-resolver-convention") version("1.0.0") } -val let = listOf("hfas") -let.forEach { +val modules = listOf("core", "wilderness", "barren", "datagen", "verification", "smoke") +modules.forEach { include(it) - var f = file("modules/$it") + val f = file("modules/$it") f.mkdirs() project(":$it").projectDir = f } -rootProject.name = "ww" +rootProject.name = "wild_wind" diff --git a/src/barren/java/org/polaris2023/wildwind/barren/BarrenMod.java b/src/barren/java/org/polaris2023/wildwind/barren/BarrenMod.java new file mode 100644 index 0000000..7576681 --- /dev/null +++ b/src/barren/java/org/polaris2023/wildwind/barren/BarrenMod.java @@ -0,0 +1,14 @@ +package org.polaris2023.wildwind.barren; +import net.minecraft.resources.Identifier; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.fml.common.Mod; +import org.polaris2023.wildwind.barren.block.ModBlocks; + +@Mod(BarrenMod.MOD_ID) +public final class BarrenMod { + public static final String MOD_ID = "wild_wind_barren"; + public BarrenMod(IEventBus bus) { + ModBlocks.register(bus); + } + public static Identifier id(String path) { return Identifier.fromNamespaceAndPath(MOD_ID, path); } +} diff --git a/src/barren/java/org/polaris2023/wildwind/barren/block/ModBlocks.java b/src/barren/java/org/polaris2023/wildwind/barren/block/ModBlocks.java new file mode 100644 index 0000000..0adf67f --- /dev/null +++ b/src/barren/java/org/polaris2023/wildwind/barren/block/ModBlocks.java @@ -0,0 +1,47 @@ +package org.polaris2023.wildwind.barren.block; + +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.block.*; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.material.MapColor; +import net.minecraft.world.level.material.PushReaction; +import net.minecraft.world.level.block.state.properties.BlockSetType; +import net.minecraft.world.level.block.state.properties.WoodType; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.neoforge.registries.DeferredBlock; +import net.neoforged.neoforge.registries.DeferredItem; +import net.neoforged.neoforge.registries.DeferredRegister; +import org.polaris2023.wildwind.barren.BarrenMod; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; + +/** + * 方块注册类 + * 使用NeoForge 26.1的DeferredRegister方式注册方块 + * 注意:方块和物品分开注册,避免延迟注册bug + * + * @author baka4n + * @since 2026/04/15 + */ +//TODO 考虑迁移至registry目录下,或将registry目录下的注册条目分散到各目录下 +public class ModBlocks { + public static final DeferredRegister.Blocks BLOCKS = DeferredRegister.createBlocks(BarrenMod.MOD_ID); + public static final DeferredRegister.Items ITEMS = DeferredRegister.createItems(BarrenMod.MOD_ID); + public static final DeferredBlock TINY_CACTUS = BLOCKS.registerBlock( + "tiny_cactus", + p -> new Block(p + .mapColor(MapColor.PLANT) + .noCollision() + .instabreak() + .sound(SoundType.WOOL) + .pushReaction(PushReaction.DESTROY)) + ); + + private static void blockItems() { + ITEMS.registerSimpleBlockItem(TINY_CACTUS); + } + public static void register(IEventBus bus) { BLOCKS.register(bus); blockItems(); ITEMS.register(bus); } +} diff --git a/src/barren/java/org/polaris2023/wildwind/barren/event/CreativeContents.java b/src/barren/java/org/polaris2023/wildwind/barren/event/CreativeContents.java new file mode 100644 index 0000000..e096518 --- /dev/null +++ b/src/barren/java/org/polaris2023/wildwind/barren/event/CreativeContents.java @@ -0,0 +1,18 @@ +package org.polaris2023.wildwind.barren.event; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.alchemy.PotionContents; +import org.polaris2023.wildwind.core.registry.ModCreativeTabs; +import org.polaris2023.wildwind.barren.BarrenMod; +import org.polaris2023.wildwind.barren.block.ModBlocks; + +@EventBusSubscriber(modid = BarrenMod.MOD_ID) +public final class CreativeContents { + @SubscribeEvent public static void populate(BuildCreativeModeTabContentsEvent event) { + if (!event.getTabKey().equals(ModCreativeTabs.WILD_WIND.getKey())) return; + ModBlocks.ITEMS.getEntries().forEach(item -> event.accept(item.get())); + + } +} diff --git a/src/barren/resources/assets/wild_wind_barren/blockstates/tiny_cactus.json b/src/barren/resources/assets/wild_wind_barren/blockstates/tiny_cactus.json new file mode 100644 index 0000000..fac7424 --- /dev/null +++ b/src/barren/resources/assets/wild_wind_barren/blockstates/tiny_cactus.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "wild_wind_barren:block/tiny_cactus" + } + } +} diff --git a/src/barren/resources/assets/wild_wind_barren/items/tiny_cactus.json b/src/barren/resources/assets/wild_wind_barren/items/tiny_cactus.json new file mode 100644 index 0000000..d93d51a --- /dev/null +++ b/src/barren/resources/assets/wild_wind_barren/items/tiny_cactus.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_barren:block/tiny_cactus" + } +} diff --git a/src/barren/resources/assets/wild_wind_barren/lang/en_us.json b/src/barren/resources/assets/wild_wind_barren/lang/en_us.json new file mode 100644 index 0000000..6e03346 --- /dev/null +++ b/src/barren/resources/assets/wild_wind_barren/lang/en_us.json @@ -0,0 +1,4 @@ +{ + "block.wild_wind_barren.tiny_cactus": "Tiny Cactus", + "mod.wild_wind.barren": "Wild Wind:Barren Update" +} diff --git a/src/barren/resources/assets/wild_wind_barren/lang/zh_cn.json b/src/barren/resources/assets/wild_wind_barren/lang/zh_cn.json new file mode 100644 index 0000000..de6f87a --- /dev/null +++ b/src/barren/resources/assets/wild_wind_barren/lang/zh_cn.json @@ -0,0 +1,4 @@ +{ + "block.wild_wind_barren.tiny_cactus": "仙人球", + "mod.wild_wind.barren": "原野之风:瘠土更新" +} diff --git a/src/barren/resources/assets/wild_wind_barren/models/block/tiny_cactus.json b/src/barren/resources/assets/wild_wind_barren/models/block/tiny_cactus.json new file mode 100644 index 0000000..6c0ef84 --- /dev/null +++ b/src/barren/resources/assets/wild_wind_barren/models/block/tiny_cactus.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cross", + "textures": { + "cross": "wild_wind_barren:block/tiny_cactus" + } +} diff --git a/src/hfas/resources/assets/ww_hfas/textures/block/tiny_cactus.png b/src/barren/resources/assets/wild_wind_barren/textures/block/tiny_cactus.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/block/tiny_cactus.png rename to src/barren/resources/assets/wild_wind_barren/textures/block/tiny_cactus.png diff --git a/src/barren/resources/data/wild_wind_barren/loot_table/blocks/tiny_cactus.json b/src/barren/resources/data/wild_wind_barren/loot_table/blocks/tiny_cactus.json new file mode 100644 index 0000000..d50b20e --- /dev/null +++ b/src/barren/resources/data/wild_wind_barren/loot_table/blocks/tiny_cactus.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_barren:tiny_cactus" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_barren:blocks/tiny_cactus" +} diff --git a/src/barren/resources/wild_wind_barren.mixins.json b/src/barren/resources/wild_wind_barren.mixins.json new file mode 100644 index 0000000..bfa6625 --- /dev/null +++ b/src/barren/resources/wild_wind_barren.mixins.json @@ -0,0 +1,13 @@ +{ + "required": true, + "package": "org.polaris2023.wildwind.barren.mixin", + "compatibilityLevel": "JAVA_25", + "mixins": [], + "injectors": { + "defaultRequire": 1 + }, + "overwrites": { + "requireAnnotations": true + }, + "client": [] +} diff --git a/src/core/java/org/polaris2023/wildwind/core/CoreMod.java b/src/core/java/org/polaris2023/wildwind/core/CoreMod.java new file mode 100644 index 0000000..3035f17 --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/core/CoreMod.java @@ -0,0 +1,23 @@ +package org.polaris2023.wildwind.core; +import net.minecraft.resources.Identifier; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.fml.common.Mod; +import org.polaris2023.wildwind.core.block.ModBlocks; +import org.polaris2023.wildwind.core.registry.*; + +@Mod(CoreMod.MOD_ID) +public final class CoreMod { + public static final String MOD_ID = "wild_wind_core"; + public CoreMod(IEventBus bus) { + ModBlocks.register(bus); + ModItems.register(bus); + org.polaris2023.wildwind.core.recipe.ModRecipes.register(bus); + org.polaris2023.wildwind.core.block.entity.ModBlockEntities.register(bus); + org.polaris2023.wildwind.core.menu.ModMenus.register(bus); + org.polaris2023.wildwind.core.worldgen.MasonKilnProcessor.PROCESSORS.register(bus); + org.polaris2023.wildwind.core.registry.ModCreativeTabs.register(bus); + org.polaris2023.wildwind.structures.StructureModule.register(bus); + + } + public static Identifier id(String path) { return Identifier.fromNamespaceAndPath(MOD_ID, path); } +} diff --git a/src/core/java/org/polaris2023/wildwind/core/api/WildWindModules.java b/src/core/java/org/polaris2023/wildwind/core/api/WildWindModules.java new file mode 100644 index 0000000..9de278d --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/core/api/WildWindModules.java @@ -0,0 +1,7 @@ +package org.polaris2023.wildwind.core.api; +import java.util.Set; +public final class WildWindModules { + private static final Set IDS = Set.of("wild_wind_core", "wild_wind_wilderness", "wild_wind_barren"); + private WildWindModules() {} + public static boolean owns(String namespace) { return IDS.contains(namespace); } +} diff --git a/src/core/java/org/polaris2023/wildwind/core/block/AzaleaShelfBlock.java b/src/core/java/org/polaris2023/wildwind/core/block/AzaleaShelfBlock.java new file mode 100644 index 0000000..c0732d0 --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/core/block/AzaleaShelfBlock.java @@ -0,0 +1,22 @@ +package org.polaris2023.wildwind.core.block; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.block.ShelfBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; + +public class AzaleaShelfBlock extends ShelfBlock { + public AzaleaShelfBlock(Properties properties) { super(properties); } + + @Override + public int getFlammability(BlockState state, BlockGetter level, BlockPos pos, Direction face) { + return state.getValue(BlockStateProperties.WATERLOGGED) ? 0 : 20; + } + + @Override + public int getFireSpreadSpeed(BlockState state, BlockGetter level, BlockPos pos, Direction face) { + return state.getValue(BlockStateProperties.WATERLOGGED) ? 0 : 30; + } +} diff --git a/src/core/java/org/polaris2023/wildwind/core/block/KilnBlock.java b/src/core/java/org/polaris2023/wildwind/core/block/KilnBlock.java new file mode 100644 index 0000000..e0aaa89 --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/core/block/KilnBlock.java @@ -0,0 +1,59 @@ +package org.polaris2023.wildwind.core.block; + +import com.mojang.serialization.MapCodec; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; +import net.minecraft.util.RandomSource; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.AbstractFurnaceBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityTicker; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import org.jspecify.annotations.Nullable; +import org.polaris2023.wildwind.core.block.entity.KilnBlockEntity; +import org.polaris2023.wildwind.core.block.entity.ModBlockEntities; + +public class KilnBlock extends AbstractFurnaceBlock { + public static final MapCodec CODEC = simpleCodec(KilnBlock::new); + + public KilnBlock(Properties properties) { super(properties); } + + @Override + public MapCodec codec() { return CODEC; } + + @Override + public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { return new KilnBlockEntity(pos, state); } + + @Override + public @Nullable BlockEntityTicker getTicker(Level level, BlockState state, BlockEntityType type) { + return level instanceof ServerLevel server ? createTickerHelper(type, ModBlockEntities.KILN.get(), + (ignored, pos, blockState, kiln) -> KilnBlockEntity.tick(server, pos, blockState, kiln)) : null; + } + + @Override + protected void openContainer(Level level, BlockPos pos, Player player) { + if (level.getBlockEntity(pos) instanceof KilnBlockEntity kiln) player.openMenu(kiln); + } + + @Override + public void animateTick(BlockState state, Level level, BlockPos pos, RandomSource random) { + if (!state.getValue(LIT)) return; + double x = pos.getX() + 0.5, y = pos.getY(), z = pos.getZ() + 0.5; + if (random.nextDouble() < 0.1) { + level.playLocalSound(x, y, z, SoundEvents.FURNACE_FIRE_CRACKLE, SoundSource.BLOCKS, 1, 1, false); + } + Direction facing = state.getValue(FACING); + double offset = random.nextDouble() * 0.6 - 0.3; + double dx = facing.getAxis() == Direction.Axis.X ? facing.getStepX() * 0.52 : offset; + double dz = facing.getAxis() == Direction.Axis.Z ? facing.getStepZ() * 0.52 : offset; + double dy = random.nextDouble() * 6 / 16; + level.addParticle(ParticleTypes.SMOKE, x + dx, y + dy, z + dz, 0, 0, 0); + level.addParticle(ParticleTypes.FLAME, x + dx, y + dy, z + dz, 0, 0, 0); + } +} diff --git a/src/core/java/org/polaris2023/wildwind/core/block/ModBlocks.java b/src/core/java/org/polaris2023/wildwind/core/block/ModBlocks.java new file mode 100644 index 0000000..33ae80c --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/core/block/ModBlocks.java @@ -0,0 +1,188 @@ +package org.polaris2023.wildwind.core.block; + +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.block.*; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.material.MapColor; +import net.minecraft.world.level.material.PushReaction; +import net.minecraft.world.level.block.state.properties.BlockSetType; +import net.minecraft.world.level.block.state.properties.WoodType; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.neoforge.registries.DeferredBlock; +import net.neoforged.neoforge.registries.DeferredItem; +import net.neoforged.neoforge.registries.DeferredRegister; +import org.polaris2023.wildwind.core.CoreMod; +import org.polaris2023.wildwind.core.worldgen.ModTreeGrowers; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; + +/** + * 方块注册类 + * 使用NeoForge 26.1的DeferredRegister方式注册方块 + * 注意:方块和物品分开注册,避免延迟注册bug + * + * @author baka4n + * @since 2026/04/15 + */ +//TODO 考虑迁移至registry目录下,或将registry目录下的注册条目分散到各目录下 +public class ModBlocks { + public static final DeferredRegister.Blocks BLOCKS = DeferredRegister.createBlocks(CoreMod.MOD_ID); + public static final DeferredRegister.Items ITEMS = DeferredRegister.createItems(CoreMod.MOD_ID); + public static final DeferredBlock KILN = BLOCKS.registerBlock("kiln", p -> new KilnBlock(p + .mapColor(MapColor.STONE).instrument(net.minecraft.world.level.block.state.properties.NoteBlockInstrument.BASEDRUM) + .requiresCorrectToolForDrops().strength(3.5F, 3.5F).sound(SoundType.STONE) + .lightLevel(state -> state.getValue(KilnBlock.LIT) ? 13 : 0).pushReaction(PushReaction.BLOCK))); + + public static final BlockSetType AZALEA_BLOCK_SET = BlockSetType.register(new BlockSetType("azalea")); + + public static final WoodType AZALEA_WOOD_TYPE = WoodType.register(new WoodType("wild_wind_core:azalea", AZALEA_BLOCK_SET)); + + public static final DeferredBlock AZALEA_LOG = BLOCKS.registerBlock( + "azalea_log", + p -> new RotatedPillarBlock(p + .mapColor(MapColor.COLOR_LIGHT_GREEN) + .strength(2.0F) + .sound(SoundType.WOOD)) + ); + + public static final DeferredBlock AZALEA_WOOD = BLOCKS.registerBlock( + "azalea_wood", + p -> new RotatedPillarBlock(p + .mapColor(MapColor.COLOR_LIGHT_GREEN) + .strength(2.0F) + .sound(SoundType.WOOD)) + ); + + public static final DeferredBlock STRIPPED_AZALEA_LOG = BLOCKS.registerBlock( + "stripped_azalea_log", + p -> new RotatedPillarBlock(p + .mapColor(MapColor.COLOR_LIGHT_GREEN) + .strength(2.0F) + .sound(SoundType.WOOD)) + ); + + public static final DeferredBlock STRIPPED_AZALEA_WOOD = BLOCKS.registerBlock( + "stripped_azalea_wood", + p -> new RotatedPillarBlock(p + .mapColor(MapColor.COLOR_LIGHT_GREEN) + .strength(2.0F) + .sound(SoundType.WOOD)) + ); + + public static final DeferredBlock AZALEA_PLANKS = BLOCKS.registerBlock( + "azalea_planks", + p -> new Block(p + .mapColor(MapColor.COLOR_LIGHT_GREEN) + .strength(2.0F) + .sound(SoundType.WOOD)) + ); + + public static final DeferredBlock AZALEA_STAIRS = BLOCKS.registerBlock( + "azalea_stairs", + p -> new StairBlock(AZALEA_PLANKS.get().defaultBlockState(), p + .mapColor(MapColor.COLOR_LIGHT_GREEN) + .strength(2.0F) + .sound(SoundType.WOOD)) + ); + + public static final DeferredBlock AZALEA_SLAB = BLOCKS.registerBlock( + "azalea_slab", + p -> new SlabBlock(p + .mapColor(MapColor.COLOR_LIGHT_GREEN) + .strength(2.0F) + .sound(SoundType.WOOD)) + ); + + public static final DeferredBlock AZALEA_FENCE = BLOCKS.registerBlock( + "azalea_fence", + p -> new FenceBlock(p + .mapColor(MapColor.COLOR_LIGHT_GREEN) + .strength(2.0F) + .sound(SoundType.WOOD)) + ); + + public static final DeferredBlock AZALEA_FENCE_GATE = BLOCKS.registerBlock( + "azalea_fence_gate", + p -> new FenceGateBlock(AZALEA_WOOD_TYPE, p + .mapColor(MapColor.COLOR_LIGHT_GREEN) + .strength(2.0F) + .sound(SoundType.WOOD)) + ); + + public static final DeferredBlock AZALEA_DOOR = BLOCKS.registerBlock( + "azalea_door", + p -> new DoorBlock(AZALEA_BLOCK_SET, p + .mapColor(MapColor.COLOR_LIGHT_GREEN) + .strength(2.0F) + .sound(SoundType.WOOD)) + ); + + public static final DeferredBlock AZALEA_TRAPDOOR = BLOCKS.registerBlock( + "azalea_trapdoor", + p -> new TrapDoorBlock(AZALEA_BLOCK_SET, p + .mapColor(MapColor.COLOR_LIGHT_GREEN) + .strength(2.0F) + .sound(SoundType.WOOD)) + ); + + public static final DeferredBlock AZALEA_PRESSURE_PLATE = BLOCKS.registerBlock( + "azalea_pressure_plate", + p -> new PressurePlateBlock(AZALEA_BLOCK_SET, p + .mapColor(MapColor.COLOR_LIGHT_GREEN) + .strength(0.5F) + .sound(SoundType.WOOD)) + ); + + public static final DeferredBlock AZALEA_BUTTON = BLOCKS.registerBlock( + "azalea_button", + p -> new ButtonBlock(AZALEA_BLOCK_SET, 30, p + .mapColor(MapColor.COLOR_LIGHT_GREEN) + .strength(0.5F) + .sound(SoundType.WOOD)) + ); + + public static final DeferredBlock AZALEA_SIGN = BLOCKS.registerBlock("azalea_sign", + p -> new StandingSignBlock(AZALEA_WOOD_TYPE, p), () -> signProperties(Blocks.OAK_SIGN)); + + public static final DeferredBlock AZALEA_WALL_SIGN = BLOCKS.registerBlock("azalea_wall_sign", + p -> new WallSignBlock(AZALEA_WOOD_TYPE, p.overrideLootTable(AZALEA_SIGN.get().getLootTable())), () -> signProperties(Blocks.OAK_WALL_SIGN)); + + public static final DeferredBlock AZALEA_HANGING_SIGN = BLOCKS.registerBlock("azalea_hanging_sign", + p -> new CeilingHangingSignBlock(AZALEA_WOOD_TYPE, p), () -> signProperties(Blocks.OAK_HANGING_SIGN)); + + public static final DeferredBlock AZALEA_WALL_HANGING_SIGN = BLOCKS.registerBlock("azalea_wall_hanging_sign", + p -> new WallHangingSignBlock(AZALEA_WOOD_TYPE, p.overrideLootTable(AZALEA_HANGING_SIGN.get().getLootTable())), () -> signProperties(Blocks.OAK_WALL_HANGING_SIGN)); + + public static final DeferredBlock AZALEA_SHELF = BLOCKS.registerBlock("azalea_shelf", + AzaleaShelfBlock::new, () -> BlockBehaviour.Properties.ofFullCopy(Blocks.OAK_SHELF) + .strength(2.0F, 3.0F).mapColor(MapColor.COLOR_LIGHT_GREEN).pushReaction(PushReaction.BLOCK)); + private static BlockBehaviour.Properties signProperties(Block template) { + return BlockBehaviour.Properties.ofFullCopy(template).strength(1.0F, 1.0F) + .mapColor(MapColor.COLOR_LIGHT_GREEN).pushReaction(PushReaction.BLOCK); + } + + + private static void blockItems() { + ITEMS.registerSimpleBlockItem(AZALEA_LOG); + ITEMS.registerSimpleBlockItem(AZALEA_WOOD); + ITEMS.registerSimpleBlockItem(STRIPPED_AZALEA_LOG); + ITEMS.registerSimpleBlockItem(STRIPPED_AZALEA_WOOD); + ITEMS.registerSimpleBlockItem(AZALEA_PLANKS); + ITEMS.registerSimpleBlockItem(AZALEA_STAIRS); + ITEMS.registerSimpleBlockItem(AZALEA_SLAB); + ITEMS.registerSimpleBlockItem(AZALEA_FENCE); + ITEMS.registerSimpleBlockItem(AZALEA_FENCE_GATE); + ITEMS.registerSimpleBlockItem(AZALEA_DOOR); + ITEMS.registerSimpleBlockItem(AZALEA_TRAPDOOR); + ITEMS.registerSimpleBlockItem(AZALEA_PRESSURE_PLATE); + ITEMS.registerSimpleBlockItem(AZALEA_BUTTON); + ITEMS.registerItem("azalea_sign", p -> new net.minecraft.world.item.SignItem(AZALEA_SIGN.get(), AZALEA_WALL_SIGN.get(), p.stacksTo(16).useBlockDescriptionPrefix())); + ITEMS.registerItem("azalea_hanging_sign", p -> new net.minecraft.world.item.HangingSignItem(AZALEA_HANGING_SIGN.get(), AZALEA_WALL_HANGING_SIGN.get(), p.stacksTo(16).useBlockDescriptionPrefix())); + ITEMS.registerSimpleBlockItem(AZALEA_SHELF, () -> new Item.Properties().component(net.minecraft.core.component.DataComponents.CONTAINER, net.minecraft.world.item.component.ItemContainerContents.EMPTY)); + ITEMS.registerSimpleBlockItem(KILN); + } + public static void register(IEventBus bus) { BLOCKS.register(bus); blockItems(); ITEMS.register(bus); } +} diff --git a/src/core/java/org/polaris2023/wildwind/core/block/entity/KilnBlockEntity.java b/src/core/java/org/polaris2023/wildwind/core/block/entity/KilnBlockEntity.java new file mode 100644 index 0000000..922a97b --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/core/block/entity/KilnBlockEntity.java @@ -0,0 +1,101 @@ +package org.polaris2023.wildwind.core.block.entity; + +import net.minecraft.core.BlockPos; +import net.minecraft.network.chat.Component; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.crafting.RecipeType; +import net.minecraft.world.item.crafting.SingleRecipeInput; +import net.minecraft.world.level.block.AbstractFurnaceBlock; +import net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import org.polaris2023.wildwind.core.menu.KilnMenu; +import org.polaris2023.wildwind.core.recipe.KilnRecipes; +import org.polaris2023.wildwind.core.mixin.FurnaceFuelAccessor; + +/** Vanilla inventory, sided transfer, persistence, locking and experience accounting; kiln-specific cooking. */ +public class KilnBlockEntity extends AbstractFurnaceBlockEntity { + public KilnBlockEntity(BlockPos pos, BlockState state) { + super(ModBlockEntities.KILN.get(), pos, state, RecipeType.SMELTING); + } + + @Override + protected Component getDefaultName() { return Component.translatable("block.wild_wind_core.kiln"); } + + @Override + protected AbstractContainerMenu createMenu(int id, Inventory inventory) { + return new KilnMenu(id, inventory, this, dataAccess); + } + + @Override + public boolean canPlaceItem(int slot, ItemStack stack) { + if (slot == SLOT_INPUT) return level != null && KilnRecipes.find(level, stack).isPresent(); + return super.canPlaceItem(slot, stack); + } + + public static void tick(ServerLevel level, BlockPos pos, BlockState state, KilnBlockEntity kiln) { + var data = kiln.dataAccess; + int rawRemaining = ((FurnaceFuelAccessor) kiln).wildwind$remainingFuel(); + boolean wasLit = rawRemaining > 0; + // Match the furnace's fuel countdown; fuel durations are unchanged (coal lasts 1600 ticks). + int remaining = Math.max(0, rawRemaining - 1); + data.set(DATA_LIT_TIME, remaining); + data.set(DATA_COOKING_TOTAL_TIME, KilnRecipes.COOK_TIME); + var input = kiln.items.get(SLOT_INPUT); + var fuel = kiln.items.get(SLOT_FUEL); + var recipe = KilnRecipes.find(level, input).orElse(null); + var result = recipe == null ? ItemStack.EMPTY : recipe.value().assemble(new SingleRecipeInput(input)); + boolean canCook = !result.isEmpty() && kiln.canAcceptResult(result); + boolean changed = wasLit; + if (remaining == 0 && canCook && !fuel.isEmpty()) { + remaining = kiln.getBurnDuration(level.fuelValues(), fuel); + data.set(DATA_LIT_TIME, remaining); + data.set(DATA_LIT_DURATION, remaining); + if (remaining > 0) { + var remainder = fuel.getCraftingRemainder(); + fuel.shrink(1); + if (fuel.isEmpty()) kiln.items.set(SLOT_FUEL, remainder == null ? ItemStack.EMPTY : remainder.create()); + changed = true; + } + } + int progress = data.get(DATA_COOKING_PROGRESS); + if (remaining > 0 && canCook) { + progress++; + if (progress >= KilnRecipes.COOK_TIME) { + progress = 0; + var output = kiln.items.get(SLOT_RESULT); + if (output.isEmpty()) kiln.items.set(SLOT_RESULT, result.copy()); + else output.grow(result.getCount()); + if (input.is(Items.WET_SPONGE) && kiln.items.get(SLOT_FUEL).is(Items.BUCKET)) { + kiln.items.set(SLOT_FUEL, new ItemStack(Items.WATER_BUCKET)); + } + input.shrink(1); + kiln.setRecipeUsed(recipe); + } + changed = true; + } else if (!canCook) { + changed |= progress != 0; + progress = 0; + } else if (progress > 0) { + progress = Math.max(0, progress - BURN_COOL_SPEED); + changed = true; + } + data.set(DATA_COOKING_PROGRESS, progress); + boolean isLit = remaining > 0; + if (state.getValue(AbstractFurnaceBlock.LIT) != isLit) { + level.setBlock(pos, state.setValue(AbstractFurnaceBlock.LIT, isLit), 3); + changed = true; + } + if (changed) kiln.setChanged(); + } + + private boolean canAcceptResult(ItemStack result) { + var output = items.get(SLOT_RESULT); + int limit = Math.min(getMaxStackSize(), result.getMaxStackSize()); + return output.isEmpty() ? result.getCount() <= limit + : ItemStack.isSameItemSameComponents(output, result) && output.getCount() + result.getCount() <= limit; + } +} diff --git a/src/core/java/org/polaris2023/wildwind/core/block/entity/ModBlockEntities.java b/src/core/java/org/polaris2023/wildwind/core/block/entity/ModBlockEntities.java new file mode 100644 index 0000000..0cf849c --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/core/block/entity/ModBlockEntities.java @@ -0,0 +1,42 @@ +package org.polaris2023.wildwind.core.block.entity; + +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.neoforge.registries.DeferredHolder; +import net.neoforged.neoforge.registries.DeferredRegister; +import org.polaris2023.wildwind.core.CoreMod; + +/** + * 方块实体注册类 + * + * @author baka4n + * @since 2026/04/15 + */ +public class ModBlockEntities { + public static final DeferredRegister> BLOCK_ENTITIES = + DeferredRegister.create(BuiltInRegistries.BLOCK_ENTITY_TYPE, CoreMod.MOD_ID); + + // 制箭台方块实体 + + + public static void register(IEventBus bus) { + BLOCK_ENTITIES.register(bus); + bus.addListener(ModBlockEntities::registerCapabilities); + bus.addListener(ModBlockEntities::addVanillaBlocks); + } + + private static void addVanillaBlocks(net.neoforged.neoforge.event.BlockEntityTypeAddBlocksEvent event) { + event.modify(net.minecraft.world.level.block.entity.BlockEntityTypes.SIGN, org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_SIGN.get(), org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_WALL_SIGN.get()); + event.modify(net.minecraft.world.level.block.entity.BlockEntityTypes.HANGING_SIGN, org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_HANGING_SIGN.get(), org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_WALL_HANGING_SIGN.get()); + event.modify(net.minecraft.world.level.block.entity.BlockEntityTypes.SHELF, org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_SHELF.get()); + } + + private static void registerCapabilities(net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent event) { + event.registerBlockEntity(net.neoforged.neoforge.capabilities.Capabilities.Item.BLOCK, KILN.get(), + net.neoforged.neoforge.transfer.item.WorldlyContainerWrapper::new); + } + + public static final DeferredHolder, BlockEntityType> KILN = + BLOCK_ENTITIES.register("kiln", () -> new BlockEntityType<>(KilnBlockEntity::new, org.polaris2023.wildwind.core.block.ModBlocks.KILN.get())); +} diff --git a/src/core/java/org/polaris2023/wildwind/core/client/AzaleaSignState.java b/src/core/java/org/polaris2023/wildwind/core/client/AzaleaSignState.java new file mode 100644 index 0000000..c6bdb8a --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/core/client/AzaleaSignState.java @@ -0,0 +1,6 @@ +package org.polaris2023.wildwind.core.client; + +public interface AzaleaSignState { + boolean wildwind$isAzalea(); + void wildwind$setAzalea(boolean azalea); +} diff --git a/src/core/java/org/polaris2023/wildwind/core/client/CoreScreens.java b/src/core/java/org/polaris2023/wildwind/core/client/CoreScreens.java new file mode 100644 index 0000000..aac65d9 --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/core/client/CoreScreens.java @@ -0,0 +1,11 @@ +package org.polaris2023.wildwind.core.client; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.client.event.RegisterMenuScreensEvent; +import org.polaris2023.wildwind.core.CoreMod; +import org.polaris2023.wildwind.core.menu.ModMenus; +@EventBusSubscriber(modid = CoreMod.MOD_ID, value = Dist.CLIENT) +public final class CoreScreens { + @SubscribeEvent public static void screens(RegisterMenuScreensEvent event) { event.register(ModMenus.KILN.get(), KilnScreen::new); } +} diff --git a/src/core/java/org/polaris2023/wildwind/core/client/KilnScreen.java b/src/core/java/org/polaris2023/wildwind/core/client/KilnScreen.java new file mode 100644 index 0000000..5df1ff8 --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/core/client/KilnScreen.java @@ -0,0 +1,38 @@ +package org.polaris2023.wildwind.core.client; + +import net.minecraft.client.gui.GuiGraphicsExtractor; +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.client.renderer.RenderPipelines; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.Identifier; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.player.Inventory; +import org.polaris2023.wildwind.core.menu.KilnMenu; + +/** Uses Minecraft's furnace artwork while keeping the kiln's server-side input rules. */ +public class KilnScreen extends AbstractContainerScreen { + private static final Identifier TEXTURE = Identifier.withDefaultNamespace("textures/gui/container/furnace.png"); + private static final Identifier FIRE = Identifier.withDefaultNamespace("container/furnace/lit_progress"); + private static final Identifier PROGRESS = Identifier.withDefaultNamespace("container/furnace/burn_progress"); + + public KilnScreen(KilnMenu menu, Inventory inventory, Component title) { super(menu, inventory, title); } + + @Override + protected void init() { + super.init(); + titleLabelX = (imageWidth - font.width(title)) / 2; + } + + @Override + public void extractBackground(GuiGraphicsExtractor graphics, int mouseX, int mouseY, float partialTick) { + super.extractBackground(graphics, mouseX, mouseY, partialTick); + graphics.blit(RenderPipelines.GUI_TEXTURED, TEXTURE, leftPos, topPos, 0, 0, imageWidth, imageHeight, 256, 256); + if (menu.isLit()) { + int height = Mth.ceil(menu.getLitProgress() * 13) + 1; + graphics.blitSprite(RenderPipelines.GUI_TEXTURED, FIRE, 14, 14, 0, 14 - height, + leftPos + 56, topPos + 50 - height, 14, height); + } + int width = Mth.ceil(menu.getBurnProgress() * 24); + if (width > 0) graphics.blitSprite(RenderPipelines.GUI_TEXTURED, PROGRESS, 24, 16, 0, 0, leftPos + 79, topPos + 34, width, 16); + } +} diff --git a/src/core/java/org/polaris2023/wildwind/core/enchantment/MeltingEnchantment.java b/src/core/java/org/polaris2023/wildwind/core/enchantment/MeltingEnchantment.java new file mode 100644 index 0000000..a69ff62 --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/core/enchantment/MeltingEnchantment.java @@ -0,0 +1,92 @@ +package org.polaris2023.wildwind.core.enchantment; + +import java.util.ArrayList; +import java.util.List; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.Identifier; +import net.minecraft.resources.ResourceKey; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.RecipeType; +import net.minecraft.world.item.crafting.SingleRecipeInput; +import net.minecraft.world.item.enchantment.Enchantment; +import net.minecraft.world.item.enchantment.EnchantmentHelper; +import net.minecraft.world.item.enchantment.Enchantments; +import net.neoforged.bus.api.EventPriority; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.event.level.BlockDropsEvent; +import org.polaris2023.wildwind.core.CoreMod; + +@EventBusSubscriber(modid = CoreMod.MOD_ID) +public final class MeltingEnchantment { + public static final ResourceKey MELTING = ResourceKey.create(Registries.ENCHANTMENT, + Identifier.fromNamespaceAndPath(CoreMod.MOD_ID, "melting")); + private MeltingEnchantment() {} + + @SubscribeEvent(priority = EventPriority.LOWEST) + public static void meltDrops(BlockDropsEvent event) { + if (!(event.getBreaker() instanceof ServerPlayer player)) return; + var registry = event.getLevel().registryAccess().lookupOrThrow(Registries.ENCHANTMENT); + if (EnchantmentHelper.getItemEnchantmentLevel(registry.getOrThrow(MELTING), event.getTool()) == 0 + || EnchantmentHelper.getItemEnchantmentLevel(registry.getOrThrow(Enchantments.SILK_TOUCH), event.getTool()) > 0) return; + + // BlockDropsEvent runs after vanilla loot (including Fortune). Plan everything before spending XP. + List conversions = new ArrayList<>(); + long cost = 0; + for (var drop : event.getDrops()) { + var stack = drop.getItem(); + var input = new SingleRecipeInput(stack.copyWithCount(1)); + var recipe = event.getLevel().recipeAccess().getRecipeFor(RecipeType.SMELTING, input, event.getLevel()); + if (recipe.isEmpty()) continue; + var result = recipe.get().value().assemble(input); + if (result.isEmpty() || ItemStack.isSameItemSameComponents(stack, result)) continue; + long outputCount = (long) result.getCount() * stack.getCount(); + if (outputCount > Integer.MAX_VALUE) return; + cost += stack.getCount(); + conversions.add(new Conversion(drop, result, (int) outputCount)); + } + if (cost == 0 || cost > Integer.MAX_VALUE || availableExperience(player) < cost) return; + if (!spendExperience(player, (int) cost)) return; + + for (var conversion : conversions) { + event.getDrops().remove(conversion.original()); + int remaining = conversion.count(); + while (remaining > 0) { + int count = Math.min(remaining, conversion.result().getMaxStackSize()); + var original = conversion.original(); + var drop = new ItemEntity(event.getLevel(), original.getX(), original.getY(), original.getZ(), + conversion.result().copyWithCount(count)); + drop.setDeltaMovement(original.getDeltaMovement()); + drop.setDefaultPickUpDelay(); + event.getDrops().add(drop); + remaining -= count; + } + } + } + + /** totalExperience is lifetime accounting and is stale after enchanting or /experience set. */ + public static long availableExperience(ServerPlayer player) { + long level = player.experienceLevel; + long base = level <= 16 ? level * level + 6 * level + : level <= 31 ? (5 * level * level - 81 * level + 720) / 2 + : (9 * level * level - 325 * level + 4440) / 2; + return base + Math.round(player.experienceProgress * player.getXpNeededForNextLevel()); + } + + private static boolean spendExperience(ServerPlayer player, int cost) { + long before = availableExperience(player); + int level = player.experienceLevel, total = player.totalExperience; + int progress = Math.round(player.experienceProgress * player.getXpNeededForNextLevel()); + player.giveExperiencePoints(-cost); + if (availableExperience(player) == before - cost) return true; + // Respect XP event cancellation/adjustment without providing free smelting or partial charges. + player.setExperienceLevels(level); + player.setExperiencePoints(progress); + player.totalExperience = total; + return false; + } + + private record Conversion(ItemEntity original, ItemStack result, int count) {} +} diff --git a/src/core/java/org/polaris2023/wildwind/core/event/CobwebBreaking.java b/src/core/java/org/polaris2023/wildwind/core/event/CobwebBreaking.java new file mode 100644 index 0000000..9c85113 --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/core/event/CobwebBreaking.java @@ -0,0 +1,86 @@ +package org.polaris2023.wildwind.core.event; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.WeakHashMap; +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.monster.spider.Spider; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.phys.Vec3; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.event.tick.EntityTickEvent; +import org.polaris2023.wildwind.core.CoreMod; + +@EventBusSubscriber(modid = CoreMod.MOD_ID) +public final class CobwebBreaking { + private static final double EPSILON = 1.0E-7; + private static final Map STATES = new WeakHashMap<>(); + private CobwebBreaking() {} + + private static boolean exempt(Entity entity) { + return entity instanceof Spider || entity.isSpectator() + || entity instanceof Player player && player.isCreative() && player.getAbilities().flying; + } + + @SubscribeEvent + public static void beforeTick(EntityTickEvent.Pre event) { + Entity entity = event.getEntity(); + if (!(entity.level() instanceof ServerLevel) || exempt(entity)) return; + // Keep a previous position across ticks for players, whose network movement occurs outside tick(). + var state = STATES.get(entity); + if (state == null && !touching(entity).isEmpty()) STATES.put(entity, new ContactState(entity.position())); + } + + @SubscribeEvent + public static void afterTick(EntityTickEvent.Post event) { tick(event.getEntity()); } + + public static void tick(Entity entity) { + if (!(entity.level() instanceof ServerLevel level)) return; + if (exempt(entity) || entity.isRemoved()) { STATES.remove(entity); return; } + Set contacts = touching(entity); + if (contacts.isEmpty()) { STATES.remove(entity); return; } + var state = STATES.get(entity); + if (state == null) { + STATES.put(entity, new ContactState(entity.position())); + return; + } + Vec3 delta = entity.position().subtract(state.previous); + state.previous = entity.position(); + state.progress.keySet().retainAll(contacts); + boolean moving = delta.lengthSqr() > EPSILON * EPSILON; + if (!moving) { state.progress.clear(); return; } + boolean falling = !entity.onGround() && delta.y < -EPSILON; + for (var pos : contacts) { + var progress = state.progress.computeIfAbsent(pos, ignored -> new Progress(falling)); + if (++progress.ticks >= (progress.falling ? 160 : 30)) { + if (level.getBlockState(pos).is(Blocks.COBWEB)) level.destroyBlock(pos, true, entity); + state.progress.remove(pos); + } + } + } + + private static Set touching(Entity entity) { + var result = new HashSet(); + for (var pos : BlockPos.betweenClosed(entity.getBoundingBox().deflate(1.0E-7))) { + if (entity.level().getBlockState(pos).is(Blocks.COBWEB)) result.add(pos.immutable()); + } + return result; + } + + private static final class ContactState { + Vec3 previous; + final Map progress = new HashMap<>(); + ContactState(Vec3 previous) { this.previous = previous; } + } + private static final class Progress { + final boolean falling; + int ticks; + Progress(boolean falling) { this.falling = falling; } + } +} diff --git a/src/core/java/org/polaris2023/wildwind/core/event/FarmlandProtection.java b/src/core/java/org/polaris2023/wildwind/core/event/FarmlandProtection.java new file mode 100644 index 0000000..3fb001e --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/core/event/FarmlandProtection.java @@ -0,0 +1,34 @@ +package org.polaris2023.wildwind.core.event; + +import net.minecraft.core.registries.Registries; +import net.minecraft.world.effect.MobEffects; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.enchantment.EnchantmentHelper; +import net.minecraft.world.item.enchantment.Enchantments; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.event.level.BlockEvent; +import org.polaris2023.wildwind.core.CoreMod; + +@EventBusSubscriber(modid = CoreMod.MOD_ID) +public final class FarmlandProtection { + private FarmlandProtection() {} + + @SubscribeEvent + public static void onTrample(BlockEvent.FarmlandTrampleEvent event) { + if (!(event.getEntity() instanceof LivingEntity entity)) return; + if (entity.hasEffect(MobEffects.SLOW_FALLING)) { + event.setCanceled(true); + return; + } + var featherFalling = entity.registryAccess().lookupOrThrow(Registries.ENCHANTMENT) + .getOrThrow(Enchantments.FEATHER_FALLING); + for (var slot : EquipmentSlot.VALUES) { + if (slot.isArmor() && EnchantmentHelper.getItemEnchantmentLevel(featherFalling, entity.getItemBySlot(slot)) > 0) { + event.setCanceled(true); + return; + } + } + } +} diff --git a/src/core/java/org/polaris2023/wildwind/core/event/FuelHandler.java b/src/core/java/org/polaris2023/wildwind/core/event/FuelHandler.java new file mode 100644 index 0000000..35b1cac --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/core/event/FuelHandler.java @@ -0,0 +1,63 @@ +package org.polaris2023.wildwind.core.event; + +import net.minecraft.world.item.Item; +import net.minecraft.world.level.block.Block; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent; +import net.neoforged.neoforge.event.furnace.FurnaceFuelBurnTimeEvent; +import org.polaris2023.wildwind.core.CoreMod; + +/** + * 燃料事件处理器 + * 为木质方块添加燃料功能 + * + * @author baka4n + * @since 2026/04/15 + */ +@EventBusSubscriber(modid = CoreMod.MOD_ID) +public class FuelHandler { + + /** + * 燃料燃烧时间事件 + * 木质方块可作为燃料,燃烧300 tick(与原版木板相同) + */ + @SubscribeEvent + public static void onFuelBurnTime(FurnaceFuelBurnTimeEvent event) { + Item item = event.getItemStack().getItem(); + + // 检查是否是木质方块物品 + int burnTime = getWoodBurnTime(item); + if (burnTime > 0) { + event.setBurnTime(burnTime); + } + } + + /** + * 获取木质方块的燃烧时间 + */ + private static int getWoodBurnTime(Item item) { + if (item == org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_SIGN.get().asItem()) return 200; + if (item == org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_HANGING_SIGN.get().asItem()) return 800; + if (item == org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_SHELF.get().asItem()) return 300; + // 焚烬木 - 300 tick(15秒) + // 灵焰木 - 300 tick + // 杜鹃木 - 300 tick + if (isAzaleaWoodItem(item)) return 300; + + return 0; + } + + + + private static boolean isAzaleaWoodItem(Item item) { + return item == org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_LOG.get().asItem() + || item == org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_WOOD.get().asItem() + || item == org.polaris2023.wildwind.core.block.ModBlocks.STRIPPED_AZALEA_LOG.get().asItem() + || item == org.polaris2023.wildwind.core.block.ModBlocks.STRIPPED_AZALEA_WOOD.get().asItem() + || item == org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_PLANKS.get().asItem() + || item == org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_SLAB.get().asItem() + || item == org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_FENCE.get().asItem() + || item == org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_FENCE_GATE.get().asItem(); + } +} diff --git a/src/core/java/org/polaris2023/wildwind/core/event/SkeletonBehavior.java b/src/core/java/org/polaris2023/wildwind/core/event/SkeletonBehavior.java new file mode 100644 index 0000000..bae181f --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/core/event/SkeletonBehavior.java @@ -0,0 +1,28 @@ +package org.polaris2023.wildwind.core.event; + +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.effect.MobEffects; +import net.minecraft.world.entity.EntityTypes; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.Mob; + +public final class SkeletonBehavior { + private SkeletonBehavior() {} + + public static boolean canSpawnWithSword(Mob mob) { + var type = mob.getType(); + return type == EntityTypes.SKELETON || type == EntityTypes.STRAY + || type == EntityTypes.BOGGED || type == EntityTypes.PARCHED; + } + + public static void afterMeleeHit(Mob attacker, LivingEntity target) { + var type = attacker.getType(); + if (type == EntityTypes.STRAY) { + target.addEffect(new MobEffectInstance(MobEffects.SLOWNESS, 600, 0), attacker); + } else if (type == EntityTypes.BOGGED) { + target.addEffect(new MobEffectInstance(MobEffects.POISON, 80, 0), attacker); + } else if (type == EntityTypes.PARCHED) { + target.addEffect(new MobEffectInstance(MobEffects.WEAKNESS, 600, 0), attacker); + } + } +} diff --git a/src/core/java/org/polaris2023/wildwind/core/inspection/BookInspectionHandler.java b/src/core/java/org/polaris2023/wildwind/core/inspection/BookInspectionHandler.java new file mode 100644 index 0000000..60ad432 --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/core/inspection/BookInspectionHandler.java @@ -0,0 +1,89 @@ +package org.polaris2023.wildwind.core.inspection; + +import java.util.ArrayList; +import java.util.List; +import net.minecraft.core.component.DataComponents; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.network.chat.Component; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.network.Filterable; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.component.WritableBookContent; +import net.minecraft.world.item.component.WrittenBookContent; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent; +import org.polaris2023.wildwind.core.CoreMod; + +@EventBusSubscriber(modid = CoreMod.MOD_ID) +public final class BookInspectionHandler { + private BookInspectionHandler() {} + + private static boolean enabled(PlayerInteractEvent event) { + return event.getEntity().isShiftKeyDown() && !event.getEntity().isSpectator() && event.getItemStack().is(Items.WRITABLE_BOOK); + } + + @SubscribeEvent + public static void block(PlayerInteractEvent.RightClickBlock event) { + if (!enabled(event)) return; + event.setCancellationResult(InteractionResult.SUCCESS); + event.setCanceled(true); + if (event.getEntity() instanceof ServerPlayer player) { + var block = player.level().getBlockState(event.getPos()).getBlock(); + var name = block.getName().copy().append("(" + BuiltInRegistries.BLOCK.getKey(block) + ")"); + record(player, event.getHand(), name, InspectionReport.block(player.level(), event.getPos())); + } + } + + @SubscribeEvent + public static void entity(PlayerInteractEvent.EntityInteract event) { + if (!enabled(event)) return; + event.setCancellationResult(InteractionResult.SUCCESS); + event.setCanceled(true); + if (event.getEntity() instanceof ServerPlayer player) { + var target = event.getTarget(); + var name = target.getType().getDescription().copy().append("(" + BuiltInRegistries.ENTITY_TYPE.getKey(target.getType()) + ")"); + record(player, event.getHand(), name, InspectionReport.entity(player.level(), target)); + } + } + + private static void record(ServerPlayer player, InteractionHand hand, Component name, List rows) { + var pages = BookPages.paginate(rows); + var signed = sign(player.getItemInHand(hand), pages, name, player.getGameProfile().name()); + if (signed.isEmpty()) { + player.sendOverlayMessage(Component.literal("书的剩余页数不足,未写入。请换一本书与笔。")); + return; + } + player.setItemInHand(hand, signed); + player.containerMenu.broadcastChanges(); + player.sendOverlayMessage(Component.literal("已生成署名属性书;松开潜行后右键阅读。")); + } + + /** Prepare a signed copy without mutating the source; an empty result means no room or wrong item. */ + public static ItemStack sign(ItemStack book, List additions, Component name, String author) { + if (!book.is(Items.WRITABLE_BOOK)) return ItemStack.EMPTY; + var old = book.getOrDefault(DataComponents.WRITABLE_BOOK_CONTENT, WritableBookContent.EMPTY); + if (old.pages().size() + additions.size() > WritableBookContent.MAX_PAGES + || additions.stream().anyMatch(page -> page.length() > WritableBookContent.PAGE_EDIT_LENGTH)) return ItemStack.EMPTY; + var pages = new ArrayList>(); + old.pages().forEach(page -> pages.add(page.map(Component::literal))); + additions.forEach(page -> pages.add(Filterable.passThrough(Component.literal(page)))); + // Vanilla's serialized title is limited to 32 characters. Keep the complete localized + // label as the display name and the full ID in the report, even for long mod IDs. + String title = name.getString(); + if (title.length() > WrittenBookContent.TITLE_MAX_LENGTH) { + int end = WrittenBookContent.TITLE_MAX_LENGTH; + if (Character.isHighSurrogate(title.charAt(end - 1))) end--; + title = title.substring(0, end); + } + var signed = book.transmuteCopy(Items.WRITTEN_BOOK); + signed.remove(DataComponents.WRITABLE_BOOK_CONTENT); + signed.set(DataComponents.WRITTEN_BOOK_CONTENT, + new WrittenBookContent(Filterable.passThrough(title), author, 0, List.copyOf(pages), true)); + signed.set(DataComponents.CUSTOM_NAME, name.copy()); + return signed; + } +} diff --git a/src/core/java/org/polaris2023/wildwind/core/inspection/BookPages.java b/src/core/java/org/polaris2023/wildwind/core/inspection/BookPages.java new file mode 100644 index 0000000..e1d8a4e --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/core/inspection/BookPages.java @@ -0,0 +1,36 @@ +package org.polaris2023.wildwind.core.inspection; + +import java.util.ArrayList; +import java.util.List; + +/** Conservative vanilla book layout: 108 pixels wide, 12 nine-pixel lines. */ +public final class BookPages { + private BookPages() {} + + public static List paginate(List rows) { + var lines = new ArrayList(); + for (String row : rows) { + for (String paragraph : row.split("\n", -1)) { + var line = new StringBuilder(); + int width = 0; + for (int cp : paragraph.codePoints().toArray()) { + // Default Latin glyphs fit within six pixels; reserve ten for other glyphs. + int glyph = cp >= 32 && cp < 127 ? 6 : 10; + if (width + glyph > 108) { + lines.add(line.toString()); + line.setLength(0); + width = 0; + } + if (!Character.isISOControl(cp)) line.appendCodePoint(cp); + width += glyph; + } + lines.add(line.toString()); + } + } + var pages = new ArrayList(); + for (int i = 0; i < lines.size(); i += 12) { + pages.add(String.join("\n", lines.subList(i, Math.min(i + 12, lines.size())))); + } + return List.copyOf(pages); + } +} diff --git a/src/core/java/org/polaris2023/wildwind/core/inspection/InspectionReport.java b/src/core/java/org/polaris2023/wildwind/core/inspection/InspectionReport.java new file mode 100644 index 0000000..fca499c --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/core/inspection/InspectionReport.java @@ -0,0 +1,175 @@ +package org.polaris2023.wildwind.core.inspection; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.ToIntFunction; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.Holder; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.registries.Registries; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.tags.TagKey; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.attributes.Attribute; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.entity.monster.cubemob.SulfurCube; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.crafting.RecipeType; +import net.minecraft.world.item.crafting.SingleRecipeInput; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.piston.PistonBaseBlock; +import net.minecraft.world.level.material.PushReaction; +import org.polaris2023.wildwind.core.CoreMod; + +/** Read-only snapshots; never reads container contents, private NBT or executes recipes. */ +public final class InspectionReport { + public static final TagKey RENEWABLE_ITEMS = TagKey.create(Registries.ITEM, CoreMod.id("inspection/renewable")); + public static final TagKey NON_RENEWABLE_ITEMS = TagKey.create(Registries.ITEM, CoreMod.id("inspection/non_renewable")); + public static final TagKey> RENEWABLE_ENTITIES = TagKey.create(Registries.ENTITY_TYPE, CoreMod.id("inspection/renewable")); + private static final List BLOCK_FIELDS = List.of("合适挖掘工具", "硬度", "爆炸抗性", "引燃几率", "烧毁几率", "熔岩可燃性", + "窒息生物", "红石导体", "压断红石线", "固体方块", "活塞推动行为", "乐器", "方块ID"); + private InspectionReport() {} + + public static List block(ServerLevel level, BlockPos pos) { + var state = level.getBlockState(pos); + var rows = header("方块", state.getBlock().getName().getString(), level, pos); + rows.add("合适挖掘工具:" + tools(state, level, pos)); + rows.add("硬度:" + number(state.getDestroySpeed(level, pos))); + rows.add("爆炸抗性:" + number(state.getBlock().getExplosionResistance())); + rows.add("引燃几率:" + fireValues(face -> state.getFireSpreadSpeed(level, pos, face))); + rows.add("烧毁几率:" + fireValues(face -> state.getFlammability(level, pos, face))); + rows.add("熔岩可燃性:" + flag(Arrays.stream(Direction.values()).anyMatch(face -> state.ignitedByLava(level, pos, face)))); + rows.add("窒息生物:" + flag(state.isSuffocating(level, pos))); + rows.add("红石导体:" + flag(state.isRedstoneConductor(level, pos))); + // Vanilla dust checks the conductor above it when connecting up a block step. + rows.add("压断红石线:" + flag(state.isRedstoneConductor(level, pos))); + rows.add("固体方块:" + flag(state.isSolid())); + rows.add("活塞推动行为:" + piston(state, level, pos)); + rows.add("乐器:" + instrument(state.instrument().getSerializedName())); + rows.add("方块ID:" + BuiltInRegistries.BLOCK.getKey(state.getBlock())); + var stack = state.getBlock().asItem().getDefaultInstance(); + appendItem(rows, level, stack); + rows.add("是否可燃:" + flag(Arrays.stream(Direction.values()).anyMatch(face -> state.isFlammable(level, pos, face)))); + rows.add("需正确工具掉落:" + flag(state.requiresCorrectToolForDrops())); + rows.add("方块状态:"); + var values = state.getValues().map(Object::toString).toList(); + rows.addAll(values.isEmpty() ? List.of("×") : values); + if (!stack.isEmpty()) SulfurProfile.of(level, stack).appendPhysics(rows); + return List.copyOf(rows); + } + + public static List entity(ServerLevel level, Entity target) { + var rows = header("实体", target.getName().getString(), level, target.blockPosition()); + rows.add("实体ID:" + BuiltInRegistries.ENTITY_TYPE.getKey(target.getType())); + // Keep the requested schema; block properties do not describe a mob or dropped item. + for (var field : BLOCK_FIELDS) rows.add(field + ":×"); + var stack = target instanceof ItemEntity item ? item.getItem() : ItemStack.EMPTY; + if (target instanceof SulfurCube cube) stack = cube.getItemBySlot(EquipmentSlot.BODY); + appendItem(rows, level, stack); + if (stack.isEmpty() && target.getType().builtInRegistryHolder().is(RENEWABLE_ENTITIES)) { + rows.set(rows.indexOf("可再生:×"), "可再生:是"); + } + rows.add("宽度:" + number(target.getBbWidth())); + rows.add("高度:" + number(target.getBbHeight())); + rows.add("火焰免疫:" + flag(target.fireImmune())); + if (target instanceof LivingEntity living) { + rows.add("生命值:" + number(living.getHealth())); + rows.add("最大生命值:" + number(living.getMaxHealth())); + rows.add("护甲:" + attribute(living, Attributes.ARMOR)); + rows.add("移动速度:" + attribute(living, Attributes.MOVEMENT_SPEED)); + rows.add("攻击伤害:" + attribute(living, Attributes.ATTACK_DAMAGE)); + rows.add("击退抗性:" + attribute(living, Attributes.KNOCKBACK_RESISTANCE)); + rows.add("当前氧气:" + living.getAirSupply()); + rows.add("最大氧气:" + living.getMaxAirSupply()); + } else { + for (var field : List.of("生命值", "最大生命值", "护甲", "移动速度", "攻击伤害", "击退抗性", "当前氧气", "最大氧气")) rows.add(field + ":×"); + } + if (target instanceof SulfurCube) { + rows.add("吸收物品ID:" + (stack.isEmpty() ? "×" : BuiltInRegistries.ITEM.getKey(stack.getItem()))); + if (stack.isEmpty()) rows.set(rows.indexOf("硫方怪原型:×"), "硫方怪原型:默认"); + SulfurProfile.of(level, stack).appendPhysics(rows); + } + return List.copyOf(rows); + } + + private static ArrayList header(String kind, String name, ServerLevel level, BlockPos pos) { + return new ArrayList<>(List.of("原野之风·属性记录", kind + ":" + name, + "维度:" + level.dimension().identifier(), "坐标:" + pos.getX() + "," + pos.getY() + "," + pos.getZ())); + } + + private static void appendItem(List rows, ServerLevel level, ItemStack stack) { + int fuel = stack.isEmpty() ? 0 : stack.getBurnTime(RecipeType.SMELTING, level.fuelValues()); + rows.add("烧炼时间:" + (fuel > 0 ? time(fuel) : "×")); + rows.add("硫方怪原型:" + (stack.isEmpty() ? "×" : SulfurProfile.of(level, stack).name())); + rows.add("最大堆叠:" + (stack.isEmpty() ? "×" : stack.getMaxStackSize())); + rows.add("可再生:" + (stack.is(NON_RENEWABLE_ITEMS) ? "否" : stack.is(RENEWABLE_ITEMS) ? "是" : "×")); + rows.add("物品ID:" + (stack.isEmpty() ? "×" : BuiltInRegistries.ITEM.getKey(stack.getItem()))); + var recipe = stack.isEmpty() ? "×" : level.recipeAccess().getRecipeFor(RecipeType.SMELTING, new SingleRecipeInput(stack), level) + .map(holder -> time(holder.value().cookingTime())).orElse("×"); + rows.add("烧炼加工时间:" + recipe); + } + + public static String piston(BlockState state, ServerLevel level, BlockPos pos) { + boolean canPush = Arrays.stream(Direction.values()).anyMatch(d -> PistonBaseBlock.isPushable(state, level, pos, d, true, d)); + if (!canPush) return "不可推动,不可拉动"; + if (state.getPistonPushReaction() == PushReaction.DESTROY) return "被推动破坏,不可拉动"; + boolean canPull = Arrays.stream(Direction.values()).anyMatch(d -> PistonBaseBlock.isPushable(state, level, pos, d, false, d.getOpposite())); + return canPull ? "可推动,可拉动" : "可推动,不可拉动"; + } + + private static String tools(BlockState state, ServerLevel level, BlockPos pos) { + if (state.getDestroySpeed(level, pos) < 0) return "×"; + var names = new ArrayList(); + tool(names, "镐", state, Items.NETHERITE_PICKAXE); + tool(names, "斧", state, Items.NETHERITE_AXE); + tool(names, "锹", state, Items.NETHERITE_SHOVEL); + tool(names, "锄", state, Items.NETHERITE_HOE); + tool(names, "剪刀", state, Items.SHEARS); + tool(names, "剑", state, Items.NETHERITE_SWORD); + return names.isEmpty() ? (state.requiresCorrectToolForDrops() ? "×" : "徒手") : String.join("、", names); + } + + private static void tool(List names, String name, BlockState state, Item item) { + var stack = item.getDefaultInstance(); + if (stack.getDestroySpeed(state) > 1 && (!state.requiresCorrectToolForDrops() || stack.isCorrectToolForDrops(state))) names.add(name); + } + + private static String fireValues(ToIntFunction getter) { + int min = Arrays.stream(Direction.values()).mapToInt(getter).min().orElse(0); + int max = Arrays.stream(Direction.values()).mapToInt(getter).max().orElse(0); + if (max == 0) return "×"; + return min == max ? Integer.toString(max) : min + "–" + max + "(随面)"; + } + + private static String instrument(String name) { + return switch (name) { + case "harp" -> "竖琴"; case "basedrum" -> "底鼓"; case "snare" -> "军鼓"; case "hat" -> "踩镲"; + case "bass" -> "贝斯"; case "flute" -> "长笛"; case "bell" -> "钟琴"; case "guitar" -> "吉他"; + case "chime" -> "管钟"; case "xylophone" -> "木琴"; case "iron_xylophone" -> "铁木琴"; + case "cow_bell" -> "牛铃"; case "didgeridoo" -> "迪吉里杜管"; case "bit" -> "方波"; + case "banjo" -> "班卓琴"; case "pling" -> "电钢琴"; + default -> name; + }; + } + + private static String attribute(LivingEntity entity, Holder key) { + var instance = entity.getAttribute(key); + return instance == null ? "×" : number(instance.getValue()); + } + + public static String number(double value) { + return Double.isFinite(value) ? BigDecimal.valueOf(value).setScale(4, RoundingMode.HALF_UP).stripTrailingZeros().toPlainString() : "×"; + } + public static String flag(boolean value) { return value ? "是" : "×"; } + private static String time(int ticks) { return number(ticks / 20.0) + "秒(" + ticks + "刻)"; } +} diff --git a/src/core/java/org/polaris2023/wildwind/core/inspection/SulfurProfile.java b/src/core/java/org/polaris2023/wildwind/core/inspection/SulfurProfile.java new file mode 100644 index 0000000..fcfd312 --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/core/inspection/SulfurProfile.java @@ -0,0 +1,65 @@ +package org.polaris2023.wildwind.core.inspection; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import net.minecraft.core.Holder; +import net.minecraft.core.registries.Registries; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.EntityTypes; +import net.minecraft.world.entity.SulfurCubeArchetype; +import net.minecraft.world.entity.ai.attributes.Attribute; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.ai.attributes.DefaultAttributes; +import net.minecraft.world.item.ItemStack; + +/** Uses the same item membership, modifier order and defaults as vanilla SulfurCube. */ +public record SulfurProfile(List> matches, boolean hasAbsorbedItem) { + private static final Map NAMES = Map.ofEntries( + Map.entry("bouncy", "弹性(橡胶球)"), Map.entry("regular", "普通(足球)"), + Map.entry("slow_flat", "缓慢平移(药球)"), Map.entry("fast_flat", "快速平移(高尔夫球)"), + Map.entry("light", "轻盈(沙滩球)"), Map.entry("fast_sliding", "快速滑行(冰球)"), + Map.entry("slow_sliding", "缓慢滑行(冰壶)"), Map.entry("slow_bouncy", "缓慢弹性"), + Map.entry("sticky", "黏性"), Map.entry("high_resistance", "高阻力"), + Map.entry("explosive", "爆炸"), Map.entry("hot", "高温")); + + public static SulfurProfile of(ServerLevel level, ItemStack stack) { + return new SulfurProfile(level.registryAccess().lookupOrThrow(Registries.SULFUR_CUBE_ARCHETYPE) + .listElements().filter(holder -> stack.is(holder.value().items())).toList(), !stack.isEmpty()); + } + + public String name() { + if (matches.isEmpty()) return "默认"; + return matches.stream().map(holder -> { + var id = holder.key().identifier(); + return id.getNamespace().equals("minecraft") ? NAMES.getOrDefault(id.getPath(), id.toString()) : id.toString(); + }).collect(Collectors.joining("、")); + } + + public double attribute(Holder attribute) { + var instance = DefaultAttributes.getSupplier(EntityTypes.SULFUR_CUBE).createInstance(ignored -> {}, attribute); + if (instance == null) return Double.NaN; + for (var holder : matches) { + for (var entry : holder.value().attributeModifiers()) { + if (entry.attribute().equals(attribute)) instance.addOrUpdateTransientModifier(entry.modifier()); + } + } + return instance.getValue(); + } + + public void appendPhysics(List rows) { + rows.add("硫方怪物理参数"); + rows.add("(当前版本/数据包)"); + rows.add("击退抗性:" + InspectionReport.number(attribute(Attributes.KNOCKBACK_RESISTANCE))); + rows.add("弹性:" + InspectionReport.number(attribute(Attributes.BOUNCINESS))); + rows.add("摩擦力修正系数:" + InspectionReport.number(attribute(Attributes.FRICTION_MODIFIER))); + rows.add("空气阻力修正系数:" + InspectionReport.number(attribute(Attributes.AIR_DRAG_MODIFIER))); + var knockback = matches.isEmpty() ? SulfurCubeArchetype.DEFAULT_KNOCKBACK_MODIFIERS + : matches.getLast().value().knockbackModifiers(); + rows.add("水平击退修正系数:" + InspectionReport.number(knockback.horizontalPower())); + rows.add("垂直击退修正系数:" + InspectionReport.number(knockback.verticalPower())); + rows.add("浮力:" + InspectionReport.flag(matches.stream().anyMatch(h -> h.value().buoyant()))); + // Vanilla playerPush derives this coefficient from resistance, only with an absorbed item. + rows.add("推动幅度:" + InspectionReport.number(hasAbsorbedItem ? Math.max(0, 1 - attribute(Attributes.KNOCKBACK_RESISTANCE)) : 0)); + } +} diff --git a/src/core/java/org/polaris2023/wildwind/core/menu/KilnMenu.java b/src/core/java/org/polaris2023/wildwind/core/menu/KilnMenu.java new file mode 100644 index 0000000..0d896ff --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/core/menu/KilnMenu.java @@ -0,0 +1,85 @@ +package org.polaris2023.wildwind.core.menu; + +import net.minecraft.util.Mth; +import net.minecraft.world.Container; +import net.minecraft.world.SimpleContainer; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.ContainerData; +import net.minecraft.world.inventory.FurnaceResultSlot; +import net.minecraft.world.inventory.SimpleContainerData; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.crafting.RecipeType; +import net.minecraft.world.level.Level; +import org.polaris2023.wildwind.core.recipe.KilnRecipes; + +public class KilnMenu extends AbstractContainerMenu { + private final Container container; + private final ContainerData data; + private final Level level; + + public KilnMenu(int id, Inventory inventory) { + this(id, inventory, new SimpleContainer(3), new SimpleContainerData(4)); + } + + public KilnMenu(int id, Inventory inventory, Container container, ContainerData data) { + super(ModMenus.KILN.get(), id); + checkContainerSize(container, 3); + checkContainerDataCount(data, 4); + this.container = container; + this.data = data; + this.level = inventory.player.level(); + addSlot(new Slot(container, 0, 56, 17) { + @Override + public boolean mayPlace(ItemStack stack) { + // Recipe lookup is server-authoritative; clients don't receive the full recipe manager. + return level.isClientSide() || KilnRecipes.find(level, stack).isPresent(); + } + }); + addSlot(new Slot(container, 1, 56, 53) { + @Override + public boolean mayPlace(ItemStack stack) { return isFuel(stack) || stack.is(Items.BUCKET); } + @Override + public int getMaxStackSize(ItemStack stack) { return stack.is(Items.BUCKET) ? 1 : super.getMaxStackSize(stack); } + }); + addSlot(new FurnaceResultSlot(inventory.player, container, 2, 116, 35)); + addStandardInventorySlots(inventory, 8, 84); + addDataSlots(data); + } + + private boolean isFuel(ItemStack stack) { return stack.getBurnTime(RecipeType.SMELTING, level.fuelValues()) > 0; } + + @Override + public boolean stillValid(Player player) { return container.stillValid(player); } + + @Override + public ItemStack quickMoveStack(Player player, int index) { + Slot slot = slots.get(index); + if (!slot.hasItem()) return ItemStack.EMPTY; + ItemStack stack = slot.getItem(), original = stack.copy(); + if (index == 2) { + if (!moveItemStackTo(stack, 3, 39, true)) return ItemStack.EMPTY; + slot.onQuickCraft(stack, original); + } else if (index < 3) { + if (!moveItemStackTo(stack, 3, 39, false)) return ItemStack.EMPTY; + } else if (!level.isClientSide() && KilnRecipes.find(level, stack).isPresent()) { + if (!moveItemStackTo(stack, 0, 1, false)) return ItemStack.EMPTY; + } else if (isFuel(stack)) { + if (!moveItemStackTo(stack, 1, 2, false)) return ItemStack.EMPTY; + } else if (index < 30) { + if (!moveItemStackTo(stack, 30, 39, false)) return ItemStack.EMPTY; + } else if (!moveItemStackTo(stack, 3, 30, false)) return ItemStack.EMPTY; + if (stack.isEmpty()) slot.setByPlayer(ItemStack.EMPTY); + else slot.setChanged(); + if (stack.getCount() == original.getCount()) return ItemStack.EMPTY; + slot.onTake(player, stack); + return original; + } + + public boolean isLit() { return data.get(0) > 0; } + public float getLitProgress() { return Mth.clamp((float) data.get(0) / Math.max(1, data.get(1)), 0, 1); } + public float getBurnProgress() { return Mth.clamp((float) data.get(2) / Math.max(1, data.get(3)), 0, 1); } +} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/menu/ModMenus.java b/src/core/java/org/polaris2023/wildwind/core/menu/ModMenus.java similarity index 57% rename from src/hfas/java/org/polaris2023/wildwind/hfas/menu/ModMenus.java rename to src/core/java/org/polaris2023/wildwind/core/menu/ModMenus.java index f1f2959..873ee4d 100644 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/menu/ModMenus.java +++ b/src/core/java/org/polaris2023/wildwind/core/menu/ModMenus.java @@ -1,4 +1,4 @@ -package org.polaris2023.wildwind.hfas.menu; +package org.polaris2023.wildwind.core.menu; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.world.flag.FeatureFlags; @@ -6,7 +6,7 @@ import net.neoforged.bus.api.IEventBus; import net.neoforged.neoforge.registries.DeferredHolder; import net.neoforged.neoforge.registries.DeferredRegister; -import org.polaris2023.wildwind.hfas.HFASMod; +import org.polaris2023.wildwind.core.CoreMod; /** * 菜单类型注册类 @@ -16,16 +16,15 @@ */ public class ModMenus { public static final DeferredRegister> MENUS = - DeferredRegister.create(BuiltInRegistries.MENU, HFASMod.MOD_ID); + DeferredRegister.create(BuiltInRegistries.MENU, CoreMod.MOD_ID); // 制箭台菜单 - public static final DeferredHolder, MenuType> FLETCHING_TABLE = - MENUS.register( - "fletching_table", - () -> new MenuType<>(FletchingTableMenu::new, FeatureFlags.DEFAULT_FLAGS) - ); + public static void register(IEventBus bus) { MENUS.register(bus); } + + public static final DeferredHolder, MenuType> KILN = + MENUS.register("kiln", () -> new MenuType<>(KilnMenu::new, FeatureFlags.DEFAULT_FLAGS)); } diff --git a/src/core/java/org/polaris2023/wildwind/core/mixin/AbstractSkeletonMixin.java b/src/core/java/org/polaris2023/wildwind/core/mixin/AbstractSkeletonMixin.java new file mode 100644 index 0000000..118119d --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/core/mixin/AbstractSkeletonMixin.java @@ -0,0 +1,25 @@ +package org.polaris2023.wildwind.core.mixin; + +import net.minecraft.util.RandomSource; +import net.minecraft.world.DifficultyInstance; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.monster.skeleton.AbstractSkeleton; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import org.polaris2023.wildwind.core.event.SkeletonBehavior; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(AbstractSkeleton.class) +public abstract class AbstractSkeletonMixin { + @Inject(method = "populateDefaultEquipmentSlots", at = @At("TAIL")) + private void wildWind$spawnWithSword(RandomSource random, DifficultyInstance difficulty, CallbackInfo ci) { + var self = (AbstractSkeleton) (Object) this; + // Spawn initialization only: loading a saved entity must never reroll its weapon. + if (SkeletonBehavior.canSpawnWithSword(self) && random.nextFloat() < 0.1F) { + self.setItemSlot(EquipmentSlot.MAINHAND, new ItemStack(Items.STONE_SWORD)); + } + } +} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/mixin/AzaleaBlockMixin.java b/src/core/java/org/polaris2023/wildwind/core/mixin/AzaleaBlockMixin.java similarity index 91% rename from src/hfas/java/org/polaris2023/wildwind/hfas/mixin/AzaleaBlockMixin.java rename to src/core/java/org/polaris2023/wildwind/core/mixin/AzaleaBlockMixin.java index da8943e..820790f 100644 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/mixin/AzaleaBlockMixin.java +++ b/src/core/java/org/polaris2023/wildwind/core/mixin/AzaleaBlockMixin.java @@ -1,11 +1,11 @@ -package org.polaris2023.wildwind.hfas.mixin; +package org.polaris2023.wildwind.core.mixin; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; import net.minecraft.util.RandomSource; import net.minecraft.world.level.block.AzaleaBlock; import net.minecraft.world.level.block.state.BlockState; -import org.polaris2023.wildwind.hfas.worldgen.ModTreeGrowers; +import org.polaris2023.wildwind.core.worldgen.ModTreeGrowers; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; diff --git a/src/core/java/org/polaris2023/wildwind/core/mixin/AzaleaSignRendererMixin.java b/src/core/java/org/polaris2023/wildwind/core/mixin/AzaleaSignRendererMixin.java new file mode 100644 index 0000000..55e66dd --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/core/mixin/AzaleaSignRendererMixin.java @@ -0,0 +1,75 @@ +package org.polaris2023.wildwind.core.mixin; + +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.gui.Font; +import net.minecraft.client.renderer.SubmitNodeCollector; +import net.minecraft.client.renderer.blockentity.AbstractSignRenderer; +import net.minecraft.client.renderer.blockentity.state.SignRenderState; +import net.minecraft.client.renderer.feature.ModelFeatureRenderer; +import net.minecraft.util.FormattedCharSequence; +import net.minecraft.world.item.DyeColor; +import net.minecraft.world.level.block.entity.SignBlockEntity; +import net.minecraft.world.level.block.entity.SignText; +import net.minecraft.world.phys.Vec3; +import org.jspecify.annotations.Nullable; +import org.polaris2023.wildwind.core.client.AzaleaSignState; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(AbstractSignRenderer.class) +public abstract class AzaleaSignRendererMixin { + @Shadow @Final private Font font; + + @Inject(method = "extractRenderState(Lnet/minecraft/world/level/block/entity/SignBlockEntity;Lnet/minecraft/client/renderer/blockentity/state/SignRenderState;FLnet/minecraft/world/phys/Vec3;Lnet/minecraft/client/renderer/feature/ModelFeatureRenderer$CrumblingOverlay;)V", at = @At("RETURN")) + private void wildwind$mark(SignBlockEntity entity, SignRenderState state, float partialTick, Vec3 camera, + ModelFeatureRenderer.@Nullable CrumblingOverlay overlay, CallbackInfo ci) { + var block = entity.getBlockState().getBlock(); + ((AzaleaSignState) state).wildwind$setAzalea(block == org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_SIGN.get() + || block == org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_WALL_SIGN.get() || block == org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_HANGING_SIGN.get() + || block == org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_WALL_HANGING_SIGN.get()); + } + + @Inject(method = "submitSignText", at = @At("HEAD"), cancellable = true) + private void wildwind$text(SignRenderState state, PoseStack pose, SubmitNodeCollector collector, SignText text, CallbackInfo ci) { + if (!((AzaleaSignState) state).wildwind$isAzalea()) return; + int color = wildwind$color(text.getColor()); + int dark = ((color >> 16 & 255) * 2 / 5 << 16) | ((color >> 8 & 255) * 2 / 5 << 8) | (color & 255) * 2 / 5; + int outline = text.hasGlowingText() ? 0xFF000000 | (color == 0 ? 0xF0EBCC : dark) : 0; + var lines = text.getRenderMessages(state.isTextFilteringEnabled, input -> { + var split = font.split(input, state.maxTextLineWidth); + return split.isEmpty() ? FormattedCharSequence.EMPTY : split.getFirst(); + }); + for (int i = 0; i < 4; i++) { + collector.submitText(pose, -font.width(lines[i]) / 2.0F, i * state.textLineHeight - 2 * state.textLineHeight, + lines[i], false, Font.DisplayMode.POLYGON_OFFSET, 15728880, + 0xFF000000 | (text.hasGlowingText() ? color : dark), 0, outline); + } + ci.cancel(); + } + + @Unique private static int wildwind$color(DyeColor color) { + return switch (color) { + case BLACK -> 0x000000; + case RED -> 0xFF0000; + case GREEN -> 0x00FF00; + case BROWN -> 0x8B4513; + case BLUE -> 0x0000FF; + case PURPLE -> 0xA020F0; + case CYAN -> 0x00FFFF; + case LIGHT_GRAY -> 0xD3D3D3; + case GRAY -> 0x808080; + case PINK -> 0xFF69B4; + case LIME -> 0xBFFF00; + case YELLOW -> 0xFFFF00; + case LIGHT_BLUE -> 0x9AC0CD; + case MAGENTA -> 0xFF00FF; + case ORANGE -> 0xFF681F; + case WHITE -> 0xFFFFFF; + }; + } +} diff --git a/src/core/java/org/polaris2023/wildwind/core/mixin/CrafterBlockMixin.java b/src/core/java/org/polaris2023/wildwind/core/mixin/CrafterBlockMixin.java new file mode 100644 index 0000000..12b2817 --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/core/mixin/CrafterBlockMixin.java @@ -0,0 +1,25 @@ +package org.polaris2023.wildwind.core.mixin; + +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import net.minecraft.core.BlockPos; +import net.minecraft.core.NonNullList; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.CraftingInput; +import net.minecraft.world.item.crafting.CraftingRecipe; +import net.minecraft.world.level.block.CrafterBlock; +import net.minecraft.world.level.block.state.BlockState; +import org.polaris2023.wildwind.core.recipe.WoolToStringRecipe; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(CrafterBlock.class) +abstract class CrafterBlockMixin { + @WrapOperation(method = "dispenseFrom", at = @At(value = "INVOKE", + target = "Lnet/minecraft/world/item/crafting/CraftingRecipe;getRemainingItems(Lnet/minecraft/world/item/crafting/CraftingInput;)Lnet/minecraft/core/NonNullList;")) + private NonNullList wildwind$damageShears(CraftingRecipe recipe, CraftingInput input, + Operation> original, BlockState state, ServerLevel level, BlockPos pos) { + return recipe instanceof WoolToStringRecipe wool ? wool.remainingItems(input, level) : original.call(recipe, input); + } +} diff --git a/src/core/java/org/polaris2023/wildwind/core/mixin/FurnaceFuelAccessor.java b/src/core/java/org/polaris2023/wildwind/core/mixin/FurnaceFuelAccessor.java new file mode 100644 index 0000000..fedfdd8 --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/core/mixin/FurnaceFuelAccessor.java @@ -0,0 +1,12 @@ +package org.polaris2023.wildwind.core.mixin; + +import net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(AbstractFurnaceBlockEntity.class) +public interface FurnaceFuelAccessor { + // ContainerData deliberately scales long burn times to fit network shorts; ticking needs the raw value. + @Accessor("litTimeRemaining") + int wildwind$remainingFuel(); +} diff --git a/src/core/java/org/polaris2023/wildwind/core/mixin/SignRenderStateMixin.java b/src/core/java/org/polaris2023/wildwind/core/mixin/SignRenderStateMixin.java new file mode 100644 index 0000000..a1e0de4 --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/core/mixin/SignRenderStateMixin.java @@ -0,0 +1,13 @@ +package org.polaris2023.wildwind.core.mixin; + +import net.minecraft.client.renderer.blockentity.state.SignRenderState; +import org.polaris2023.wildwind.core.client.AzaleaSignState; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; + +@Mixin(SignRenderState.class) +public abstract class SignRenderStateMixin implements AzaleaSignState { + @Unique private boolean wildwind$azalea; + public boolean wildwind$isAzalea() { return wildwind$azalea; } + public void wildwind$setAzalea(boolean azalea) { wildwind$azalea = azalea; } +} diff --git a/src/core/java/org/polaris2023/wildwind/core/mixin/SinglePoolElementMixin.java b/src/core/java/org/polaris2023/wildwind/core/mixin/SinglePoolElementMixin.java new file mode 100644 index 0000000..e2cd299 --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/core/mixin/SinglePoolElementMixin.java @@ -0,0 +1,31 @@ +package org.polaris2023.wildwind.core.mixin; + +import com.mojang.datafixers.util.Either; +import net.minecraft.resources.Identifier; +import net.minecraft.world.level.block.Rotation; +import net.minecraft.world.level.levelgen.structure.BoundingBox; +import net.minecraft.world.level.levelgen.structure.pools.SinglePoolElement; +import net.minecraft.world.level.levelgen.structure.templatesystem.LiquidSettings; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; +import org.polaris2023.wildwind.core.worldgen.MasonKilnProcessor; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(SinglePoolElement.class) +abstract class SinglePoolElementMixin { + @Shadow @Final protected Either template; + + @Inject(method = "getSettings", at = @At("RETURN")) + private void wildwind$addMasonKiln(Rotation rotation, BoundingBox box, LiquidSettings liquids, boolean keepJigsaws, + CallbackInfoReturnable cir) { + template.left().ifPresent(id -> { + var processor = MasonKilnProcessor.HOUSES.get(id); + if (processor != null) cir.getReturnValue().addProcessor(processor); + }); + } +} diff --git a/src/core/java/org/polaris2023/wildwind/core/mixin/SkeletonMeleeMixin.java b/src/core/java/org/polaris2023/wildwind/core/mixin/SkeletonMeleeMixin.java new file mode 100644 index 0000000..f3a6fc2 --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/core/mixin/SkeletonMeleeMixin.java @@ -0,0 +1,18 @@ +package org.polaris2023.wildwind.core.mixin; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.Mob; +import org.polaris2023.wildwind.core.event.SkeletonBehavior; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +@Mixin(Mob.class) +public abstract class SkeletonMeleeMixin { + @Inject(method = "doHurtTarget", at = @At("RETURN")) + private void wildWind$meleeEffects(ServerLevel level, Entity target, CallbackInfoReturnable cir) { + if (cir.getReturnValueZ() && target instanceof LivingEntity living) + SkeletonBehavior.afterMeleeHit((Mob)(Object)this, living); + } +} diff --git a/src/core/java/org/polaris2023/wildwind/core/recipe/KilnRecipes.java b/src/core/java/org/polaris2023/wildwind/core/recipe/KilnRecipes.java new file mode 100644 index 0000000..40b63a2 --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/core/recipe/KilnRecipes.java @@ -0,0 +1,36 @@ +package org.polaris2023.wildwind.core.recipe; + +import java.util.Optional; +import net.minecraft.core.registries.Registries; +import net.minecraft.tags.TagKey; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.RecipeHolder; +import net.minecraft.world.item.crafting.RecipeType; +import net.minecraft.world.item.crafting.SingleRecipeInput; +import net.minecraft.world.item.crafting.SmeltingRecipe; +import net.minecraft.world.level.Level; +import net.minecraft.server.level.ServerLevel; +import org.polaris2023.wildwind.core.CoreMod; + +/** Reuses the current world's smelting recipes, including data-pack recipes and their experience. */ +public final class KilnRecipes { + public static final int COOK_TIME = 100; + public static final TagKey EXCLUDED = TagKey.create(Registries.ITEM, CoreMod.id("kiln_excluded")); + private static final TagKey METAL_OUTPUTS = TagKey.create(Registries.ITEM, CoreMod.id("kiln_metal_outputs")); + + private KilnRecipes() {} + + public static Optional> find(Level level, ItemStack stack) { + if (!(level instanceof ServerLevel server) || stack.isEmpty() || stack.is(EXCLUDED)) return Optional.empty(); + var input = new SingleRecipeInput(stack); + // Blasting covers metal equipment recycling as well as ore/raw-metal processing. + if (server.recipeAccess().getRecipeFor(RecipeType.BLASTING, input, server).isPresent()) return Optional.empty(); + var recipe = server.recipeAccess().getRecipeFor(RecipeType.SMELTING, input, server); + if (recipe.isPresent() && stack.isDamageableItem() + && recipe.get().value().assemble(input).is(METAL_OUTPUTS)) { + return Optional.empty(); + } + return recipe; + } +} diff --git a/src/core/java/org/polaris2023/wildwind/core/recipe/ModRecipes.java b/src/core/java/org/polaris2023/wildwind/core/recipe/ModRecipes.java new file mode 100644 index 0000000..aa9fb33 --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/core/recipe/ModRecipes.java @@ -0,0 +1,20 @@ +package org.polaris2023.wildwind.core.recipe; + +import com.mojang.serialization.MapCodec; +import net.minecraft.core.registries.Registries; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.world.item.crafting.RecipeSerializer; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.neoforge.registries.DeferredHolder; +import net.neoforged.neoforge.registries.DeferredRegister; +import org.polaris2023.wildwind.core.CoreMod; + +public final class ModRecipes { + private static final DeferredRegister> SERIALIZERS = DeferredRegister.create(Registries.RECIPE_SERIALIZER, CoreMod.MOD_ID); + public static final DeferredHolder, RecipeSerializer> WOOL_TO_STRING = + SERIALIZERS.register("wool_to_string", () -> new RecipeSerializer<>( + MapCodec.unit(WoolToStringRecipe.INSTANCE), StreamCodec.unit(WoolToStringRecipe.INSTANCE))); + + private ModRecipes() {} + public static void register(IEventBus bus) { SERIALIZERS.register(bus); } +} diff --git a/src/core/java/org/polaris2023/wildwind/core/recipe/WoolToStringRecipe.java b/src/core/java/org/polaris2023/wildwind/core/recipe/WoolToStringRecipe.java new file mode 100644 index 0000000..fad8e6d --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/core/recipe/WoolToStringRecipe.java @@ -0,0 +1,70 @@ +package org.polaris2023.wildwind.core.recipe; + +import java.util.List; +import net.minecraft.core.NonNullList; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.tags.ItemTags; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.ItemStackTemplate; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.crafting.CraftingInput; +import net.minecraft.world.item.crafting.CustomRecipe; +import net.minecraft.world.item.crafting.RecipeSerializer; +import net.minecraft.world.item.crafting.display.RecipeDisplay; +import net.minecraft.world.item.crafting.display.ShapelessCraftingRecipeDisplay; +import net.minecraft.world.item.crafting.display.SlotDisplay; +import net.minecraft.world.level.Level; +import net.neoforged.neoforge.common.CommonHooks; +import org.jspecify.annotations.Nullable; + +public final class WoolToStringRecipe extends CustomRecipe { + public static final WoolToStringRecipe INSTANCE = new WoolToStringRecipe(); + private WoolToStringRecipe() {} + + @Override + public boolean matches(CraftingInput input, Level level) { + if (input.ingredientCount() != 2) return false; + boolean wool = false, shears = false; + for (var stack : input.items()) { + if (stack.isEmpty()) continue; + if (!wool && stack.is(ItemTags.WOOL)) wool = true; + else if (!shears && stack.is(Items.SHEARS) && !stack.isBroken()) shears = true; + else return false; + } + return wool && shears; + } + + @Override + public ItemStack assemble(CraftingInput input) { return new ItemStack(Items.STRING, 2); } + + @Override + public RecipeSerializer getSerializer() { return ModRecipes.WOOL_TO_STRING.get(); } + + @Override + public NonNullList getRemainingItems(CraftingInput input) { + var player = CommonHooks.getCraftingPlayer(); + return remainingItems(input, player != null && player.level() instanceof ServerLevel level ? level : null); + } + + /** CrafterBlock also supplies its server level; recipe previews never roll durability RNG. */ + public NonNullList remainingItems(CraftingInput input, @Nullable ServerLevel level) { + var remaining = NonNullList.withSize(input.size(), ItemStack.EMPTY); + for (int slot = 0; slot < input.size(); slot++) { + if (input.getItem(slot).is(Items.SHEARS)) { + var shears = input.getItem(slot).copyWithCount(1); + if (level != null) shears.hurtAndBreak(1, level, (LivingEntity) null, item -> {}); + remaining.set(slot, shears.isEmpty() ? ItemStack.EMPTY : shears); + } + } + return remaining; + } + + @Override + public List display() { + return List.of(new ShapelessCraftingRecipeDisplay(List.of(new SlotDisplay.TagSlotDisplay(ItemTags.WOOL), + new SlotDisplay.WithRemainder(new SlotDisplay.ItemSlotDisplay(Items.SHEARS), new SlotDisplay.ItemSlotDisplay(Items.SHEARS))), + new SlotDisplay.ItemStackSlotDisplay(new ItemStackTemplate(Items.STRING, 2)), + new SlotDisplay.ItemSlotDisplay(Items.CRAFTING_TABLE))); + } +} diff --git a/src/core/java/org/polaris2023/wildwind/core/registry/ModCreativeTabs.java b/src/core/java/org/polaris2023/wildwind/core/registry/ModCreativeTabs.java new file mode 100644 index 0000000..4f4de35 --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/core/registry/ModCreativeTabs.java @@ -0,0 +1,70 @@ +package org.polaris2023.wildwind.core.registry; + +import org.polaris2023.wildwind.core.registry.ModItems; +import org.polaris2023.wildwind.core.block.ModBlocks; +import net.minecraft.core.registries.Registries; +import net.minecraft.network.chat.Component; +import net.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.alchemy.PotionContents; +import net.minecraft.core.component.DataComponents; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.world.item.enchantment.EnchantmentHelper; +import net.minecraft.world.item.enchantment.EnchantmentInstance; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent; +import org.polaris2023.wildwind.core.enchantment.MeltingEnchantment; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.neoforge.registries.DeferredHolder; +import net.neoforged.neoforge.registries.DeferredRegister; +import org.polaris2023.wildwind.core.CoreMod; + +@EventBusSubscriber(modid = CoreMod.MOD_ID) +public class ModCreativeTabs { + public static final DeferredRegister CREATIVE_TABS = + DeferredRegister.create(Registries.CREATIVE_MODE_TAB, CoreMod.MOD_ID); + /** + * 模组专用创造模式物品栏喵~ + */ + public static final DeferredHolder WILD_WIND = + CREATIVE_TABS.register("wild_wind", () -> CreativeModeTab.builder() + .title(Component.translatable("mod.wild_wind.name")) + .icon(() -> org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_PLANKS.get().asItem().getDefaultInstance()) + .displayItems((params, output) -> { + addStacks(output); + output.accept(EnchantmentHelper.createBook(new EnchantmentInstance( + params.holders().lookupOrThrow(Registries.ENCHANTMENT).getOrThrow(MeltingEnchantment.MELTING), 1))); + }) + .build() + ); + + /** + * 向模组事件总线注册创造模式物品栏 + * + * @param modBus 模组事件总线喵~ + */ + public static void register(IEventBus modBus) { + CREATIVE_TABS.register(modBus); + } + + @SubscribeEvent + public static void keepModContentsInOwnTab(BuildCreativeModeTabContentsEvent event) { + if (event.getTab().getType() != CreativeModeTab.Type.CATEGORY + || !event.getTabKey().identifier().getNamespace().equals("minecraft")) return; + // Vanilla generators also discover mod potions and enchanted books automatically. + event.removeIf(stack -> { + if (org.polaris2023.wildwind.core.api.WildWindModules.owns(BuiltInRegistries.ITEM.getKey(stack.getItem()).getNamespace())) return true; + var potion = stack.get(DataComponents.POTION_CONTENTS); + if (potion != null && potion.potion().isPresent() + && org.polaris2023.wildwind.core.api.WildWindModules.owns(potion.potion().get().unwrapKey().orElseThrow().identifier().getNamespace())) return true; + var enchantments = stack.get(DataComponents.STORED_ENCHANTMENTS); + return enchantments != null && enchantments.keySet().stream().anyMatch(holder -> holder.is(MeltingEnchantment.MELTING)); + }, CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); + } + + private static void addStacks(CreativeModeTab.Output output) { + ModBlocks.ITEMS.getEntries().forEach(item -> output.accept(item.get())); + ModItems.ITEMS.getEntries().forEach(item -> output.accept(item.get())); + } +} diff --git a/src/core/java/org/polaris2023/wildwind/core/registry/ModItems.java b/src/core/java/org/polaris2023/wildwind/core/registry/ModItems.java new file mode 100644 index 0000000..a4b6b9b --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/core/registry/ModItems.java @@ -0,0 +1,49 @@ +package org.polaris2023.wildwind.core.registry; + +import net.minecraft.core.Holder; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.MobBucketItem; +import net.minecraft.world.item.SpawnEggItem; +import net.minecraft.world.level.material.Fluids; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.neoforge.registries.DeferredItem; +import net.neoforged.neoforge.registries.DeferredRegister; +import org.polaris2023.wildwind.core.CoreMod; + +import java.util.function.Function; +import java.util.List; + +public class ModItems { + public static final DeferredRegister.Items ITEMS = DeferredRegister.createItems(CoreMod.MOD_ID); + public static final DeferredItem DUCKWEED = register("duckweed"); + public static final DeferredItem CALAMARI = register("calamari"); + public static final DeferredItem COOKED_CALAMARI = register("cooked_calamari"); + public static final DeferredItem COOKED_EGG = register("cooked_egg"); + public static final DeferredItem BAKED_SEEDS = register("baked_seeds"); + public static final DeferredItem COOKED_FROG_LEGS = register("cooked_frog_legs"); + public static final DeferredItem FROG_LEGS = register("frog_legs"); + public static final List> MATERIALS = List.of( + DUCKWEED, CALAMARI, COOKED_CALAMARI, COOKED_EGG, BAKED_SEEDS, COOKED_FROG_LEGS, FROG_LEGS); + public static void register(IEventBus modBus) { + ITEMS.register(modBus); + } + + + public static DeferredItem registerMobEgg(String id, Holder> type){ + return ITEMS.registerItem(id, p -> new SpawnEggItem(p.spawnEgg(type.value()))); + } + + public static DeferredItem register(String id){ + return ITEMS.registerItem(id, Item::new); + } + + public static DeferredItem register(String id, Function builder){ + return ITEMS.registerItem(id, builder); + } + + public static DeferredItem register(String id, Function builder, Function property){ + return ITEMS.registerItem(id, p -> builder.apply(property.apply(p))); + } +} diff --git a/src/core/java/org/polaris2023/wildwind/core/worldgen/MasonKilnProcessor.java b/src/core/java/org/polaris2023/wildwind/core/worldgen/MasonKilnProcessor.java new file mode 100644 index 0000000..87d0f64 --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/core/worldgen/MasonKilnProcessor.java @@ -0,0 +1,56 @@ +package org.polaris2023.wildwind.core.worldgen; + +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import java.util.Map; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.Identifier; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessor; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; +import net.neoforged.neoforge.registries.DeferredRegister; +import org.jspecify.annotations.Nullable; +import org.polaris2023.wildwind.core.CoreMod; +import org.polaris2023.wildwind.core.block.KilnBlock; + +/** Inserts a kiln beside the workstation in each of the six vanilla mason-house templates. */ +public record MasonKilnProcessor(BlockPos target, Direction facing, Block replacedBlock) implements StructureProcessor { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + BlockPos.CODEC.fieldOf("pos").forGetter(MasonKilnProcessor::target), + Direction.CODEC.fieldOf("facing").forGetter(MasonKilnProcessor::facing), + BuiltInRegistries.BLOCK.byNameCodec().fieldOf("replace").forGetter(MasonKilnProcessor::replacedBlock) + ).apply(instance, MasonKilnProcessor::new)); + public static final DeferredRegister> PROCESSORS = + DeferredRegister.create(Registries.STRUCTURE_PROCESSOR, CoreMod.MOD_ID); + static { PROCESSORS.register("mason_kiln", () -> CODEC); } + + public static final Map HOUSES = Map.of( + id("desert/houses/desert_mason_1"), new MasonKilnProcessor(new BlockPos(5, 1, 6), Direction.NORTH, Blocks.AIR), + id("plains/houses/plains_masons_house_1"), new MasonKilnProcessor(new BlockPos(5, 1, 6), Direction.NORTH, Blocks.AIR), + id("savanna/houses/savanna_mason_1"), new MasonKilnProcessor(new BlockPos(5, 1, 2), Direction.SOUTH, Blocks.AIR), + id("snowy/houses/snowy_masons_house_1"), new MasonKilnProcessor(new BlockPos(6, 2, 5), Direction.WEST, Blocks.SPRUCE_PLANKS), + id("snowy/houses/snowy_masons_house_2"), new MasonKilnProcessor(new BlockPos(5, 1, 2), Direction.SOUTH, Blocks.DIORITE_STAIRS), + id("taiga/houses/taiga_masons_house_1"), new MasonKilnProcessor(new BlockPos(5, 2, 5), Direction.WEST, Blocks.AIR)); + + private static Identifier id(String path) { return Identifier.withDefaultNamespace("village/" + path); } + + @Override + public MapCodec codec() { return CODEC; } + + @Override + public StructureTemplate.@Nullable StructureBlockInfo process(LevelReader level, BlockPos origin, BlockPos reference, + StructureTemplate.StructureBlockInfo original, StructureTemplate.StructureBlockInfo processed, + StructurePlaceSettings settings, @Nullable StructureTemplate template) { + // Do not overwrite a chest/workstation if a data pack redesigns this template. + if (!original.pos().equals(target) || !original.state().is(replacedBlock) || !processed.state().is(replacedBlock)) return processed; + // StructureTemplate applies mirror/rotation to the state after processing; position is already transformed. + return new StructureTemplate.StructureBlockInfo(processed.pos(), + org.polaris2023.wildwind.core.block.ModBlocks.KILN.get().defaultBlockState().setValue(KilnBlock.FACING, facing), null); + } +} diff --git a/src/core/java/org/polaris2023/wildwind/core/worldgen/ModTreeGrowers.java b/src/core/java/org/polaris2023/wildwind/core/worldgen/ModTreeGrowers.java new file mode 100644 index 0000000..a922dfc --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/core/worldgen/ModTreeGrowers.java @@ -0,0 +1,9 @@ +package org.polaris2023.wildwind.core.worldgen; +import net.minecraft.world.level.block.grower.TreeGrower; +import net.minecraft.resources.ResourceKey; +import net.minecraft.core.registries.Registries; +import java.util.Optional; +import org.polaris2023.wildwind.core.CoreMod; +public final class ModTreeGrowers { + public static final TreeGrower AZALEA = new TreeGrower("wild_wind_core:azalea", Optional.empty(), Optional.of(ResourceKey.create(Registries.CONFIGURED_FEATURE, CoreMod.id("azalea_tree"))), Optional.empty()); +} diff --git a/src/core/java/org/polaris2023/wildwind/structures/StructureModule.java b/src/core/java/org/polaris2023/wildwind/structures/StructureModule.java new file mode 100644 index 0000000..642d5e1 --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/structures/StructureModule.java @@ -0,0 +1,35 @@ +package org.polaris2023.wildwind.structures; + +import net.minecraft.core.registries.Registries; +import net.minecraft.world.level.levelgen.structure.StructureType; +import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceType; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.neoforge.common.NeoForge; +import net.neoforged.neoforge.registries.DeferredHolder; +import net.neoforged.neoforge.registries.DeferredRegister; +import org.polaris2023.wildwind.structures.command.StructureCommands; +import org.polaris2023.wildwind.structures.config.ConfigStructurePack; +import org.polaris2023.wildwind.structures.worldgen.ConfiguredStructure; +import org.polaris2023.wildwind.structures.worldgen.ConfiguredTemplatePiece; +import org.polaris2023.wildwind.structures.worldgen.GeneratedStructureIndex; + +public final class StructureModule { + // Keep registry and saved-data IDs compatible with the former standalone module. + public static final String NAMESPACE = "ww_structures"; + private static final DeferredRegister> TYPES = DeferredRegister.create(Registries.STRUCTURE_TYPE, NAMESPACE); + private static final DeferredRegister PIECES = DeferredRegister.create(Registries.STRUCTURE_PIECE, NAMESPACE); + public static final DeferredHolder, StructureType> STRUCTURE = + TYPES.register("configured", () -> () -> ConfiguredStructure.CODEC); + public static final DeferredHolder PIECE = + PIECES.register("template", () -> ConfiguredTemplatePiece::new); + + private StructureModule() {} + + public static void register(IEventBus bus) { + TYPES.register(bus); + PIECES.register(bus); + bus.addListener(ConfigStructurePack::addPack); + NeoForge.EVENT_BUS.addListener(StructureCommands::register); + NeoForge.EVENT_BUS.addListener(GeneratedStructureIndex::onChunkLoad); + } +} diff --git a/src/core/java/org/polaris2023/wildwind/structures/command/StructureCommands.java b/src/core/java/org/polaris2023/wildwind/structures/command/StructureCommands.java new file mode 100644 index 0000000..d07d89e --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/structures/command/StructureCommands.java @@ -0,0 +1,91 @@ +package org.polaris2023.wildwind.structures.command; + +import com.mojang.brigadier.arguments.IntegerArgumentType; +import com.mojang.brigadier.arguments.StringArgumentType; +import java.util.TreeSet; +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.Commands; +import net.minecraft.commands.SharedSuggestionProvider; +import net.minecraft.core.BlockPos; +import net.minecraft.core.HolderSet; +import net.minecraft.core.registries.Registries; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.Identifier; +import net.minecraft.resources.ResourceKey; +import net.minecraft.server.permissions.Permissions; +import net.neoforged.neoforge.event.RegisterCommandsEvent; +import org.polaris2023.wildwind.structures.StructureModule; +import org.polaris2023.wildwind.structures.worldgen.ConfiguredStructure; +import org.polaris2023.wildwind.structures.worldgen.GeneratedStructureIndex; + +public final class StructureCommands { + public static void register(RegisterCommandsEvent event) { + event.getDispatcher().register(Commands.literal("wwstructure") + .requires(source -> source.permissions().hasPermission(Permissions.COMMANDS_GAMEMASTER)) + .then(Commands.literal("list").executes(context -> { + var names = names(context.getSource()); + context.getSource().sendSuccess(() -> Component.literal("结构名称(配置或当前维度历史记录):" + String.join(", ", names)), false); + return names.size(); + })) + .then(Commands.literal("locate").then(Commands.argument("name", StringArgumentType.word()) + .suggests((context, builder) -> SharedSuggestionProvider.suggest(names(context.getSource()), builder)) + .executes(context -> locate(context.getSource(), StringArgumentType.getString(context, "name"))))) + .then(Commands.literal("search").then(Commands.argument("name", StringArgumentType.word()) + .suggests((context, builder) -> SharedSuggestionProvider.suggest(names(context.getSource()), builder)) + .executes(context -> search(context.getSource(), StringArgumentType.getString(context, "name"), 16)) + .then(Commands.argument("radius", IntegerArgumentType.integer(1, 64)) + .executes(context -> search(context.getSource(), StringArgumentType.getString(context, "name"), + IntegerArgumentType.getInteger(context, "radius"))))))); + } + + private static TreeSet names(CommandSourceStack source) { + TreeSet names = new TreeSet<>(); + source.registryAccess().lookupOrThrow(Registries.STRUCTURE).listElements() + .filter(holder -> holder.value() instanceof ConfiguredStructure) + .forEach(holder -> names.add(holder.key().identifier().toString())); + source.getLevel().getDataStorage().computeIfAbsent(GeneratedStructureIndex.TYPE).names() + .forEach(id -> names.add(id.toString())); + return names; + } + + private static Identifier id(String name) { + return Identifier.tryParse(name.contains(":") ? name : StructureModule.NAMESPACE + ":" + name); + } + + private static int locate(CommandSourceStack source, String name) { + Identifier id = id(name); + if (id == null) { source.sendFailure(Component.literal("无效的结构名称:" + name)); return 0; } + var found = source.getLevel().getDataStorage().computeIfAbsent(GeneratedStructureIndex.TYPE) + .nearest(id, BlockPos.containing(source.getPosition())); + if (found.isEmpty()) { + source.sendFailure(Component.literal("当前维度没有该结构的已生成记录:" + id + "。可用 /wwstructure search " + name + " 寻找生成位置。")); + return 0; + } + return report(source, id, found.get(), "最近的已生成结构"); + } + + private static int search(CommandSourceStack source, String name, int radius) { + Identifier id = id(name); + if (id == null) { source.sendFailure(Component.literal("无效的结构名称:" + name)); return 0; } + var holder = source.registryAccess().lookupOrThrow(Registries.STRUCTURE).get(ResourceKey.create(Registries.STRUCTURE, id)); + if (holder.isEmpty() || !(holder.get().value() instanceof ConfiguredStructure)) { + source.sendFailure(Component.literal("未启用或不存在的结构:" + id)); + return 0; + } + var level = source.getLevel(); + var found = level.getChunkSource().getGenerator().findNearestMapStructure(level, HolderSet.direct(holder.get()), + BlockPos.containing(source.getPosition()), radius, false); + if (found == null) { + source.sendFailure(Component.literal("搜索范围内未找到 " + id + ";请检查群系、生成条件和世界的结构生成开关。")); + return 0; + } + return report(source, id, found.getFirst(), "原版搜索结果(可能尚未生成完整区块)"); + } + + private static int report(CommandSourceStack source, Identifier id, BlockPos position, String label) { + int distance = (int) Math.sqrt(GeneratedStructureIndex.horizontalDistanceSquared(position, BlockPos.containing(source.getPosition()))); + source.sendSuccess(() -> Component.literal(label + " " + id + ": [" + position.getX() + ", " + position.getY() + ", " + + position.getZ() + "],维度 " + source.getLevel().dimension().identifier() + ",水平距离 " + distance + " 格"), false); + return 1; + } +} diff --git a/src/core/java/org/polaris2023/wildwind/structures/config/ConfigStructurePack.java b/src/core/java/org/polaris2023/wildwind/structures/config/ConfigStructurePack.java new file mode 100644 index 0000000..2d23754 --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/structures/config/ConfigStructurePack.java @@ -0,0 +1,229 @@ +package org.polaris2023.wildwind.structures.config; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.mojang.logging.LogUtils; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import net.minecraft.SharedConstants; +import net.minecraft.nbt.NbtAccounter; +import net.minecraft.nbt.NbtIo; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.Identifier; +import net.minecraft.server.packs.PackLocationInfo; +import net.minecraft.server.packs.PackResources; +import net.minecraft.server.packs.PackSelectionConfig; +import net.minecraft.server.packs.PackType; +import net.minecraft.server.packs.metadata.pack.PackMetadataSection; +import net.minecraft.server.packs.repository.Pack; +import net.minecraft.server.packs.repository.PackSource; +import net.minecraft.server.packs.resources.IoSupplier; +import net.minecraft.util.InclusiveRange; +import net.neoforged.fml.loading.FMLPaths; +import net.neoforged.neoforge.event.AddPackFindersEvent; +import net.neoforged.neoforge.resource.EmptyPackResources; +import org.polaris2023.wildwind.structures.StructureModule; + +/** Each server repository gets one immutable snapshot, including template bytes. */ +public final class ConfigStructurePack extends EmptyPackResources { + private static final Gson JSON = new GsonBuilder().setPrettyPrinting().create(); + private final Map resources; + + private ConfigStructurePack(PackLocationInfo info, Map resources) { + super(info, new PackMetadataSection(Component.literal("Wild Wind configured structures"), + new InclusiveRange<>(SharedConstants.getCurrentVersion().packVersion(PackType.SERVER_DATA)))); + this.resources = resources; + } + + public static void addPack(AddPackFindersEvent event) { + if (event.getPackType() != PackType.SERVER_DATA || event.isTrusted()) return; + Path root = FMLPaths.CONFIGDIR.get().resolve(StructureModule.NAMESPACE); + final Map snapshot; + try { + snapshot = load(root); + } catch (IOException | RuntimeException exception) { + // Fail before registries load; silently dropping a bad definition would change the world. + throw new IllegalStateException("Cannot load structure config at " + root + ": " + exception.getMessage(), exception); + } + var supplier = new Pack.ResourcesSupplier() { + @Override public PackResources openPrimary(PackLocationInfo info) { return new ConfigStructurePack(info, snapshot); } + @Override public PackResources openFull(PackLocationInfo info, Pack.Metadata metadata) { return openPrimary(info); } + }; + var pack = Pack.readMetaAndCreate(new PackLocationInfo("ww_structures/config", + Component.literal("Wild Wind · 结构生成配置"), PackSource.DEFAULT, Optional.empty()), + supplier, PackType.SERVER_DATA, new PackSelectionConfig(true, Pack.Position.TOP, false)); + if (pack == null) throw new IllegalStateException("Could not create structure configuration datapack"); + event.addRepositorySource(consumer -> consumer.accept(pack)); + } + + public static Map load(Path root) throws IOException { + Files.createDirectories(root.resolve("definitions")); + Files.createDirectories(root.resolve("templates")); + Path example = root.resolve("example_ruins.json.disabled"); + if (Files.notExists(example)) { + try (InputStream input = ConfigStructurePack.class.getResourceAsStream("/examples/example_ruins.json")) { + if (input == null) throw new IOException("Missing bundled example"); + Files.copy(input, example); + } + } + Path exampleTemplate = root.resolve("templates/example_ruins.nbt"); + if (Files.notExists(exampleTemplate)) { + try (InputStream input = ConfigStructurePack.class.getResourceAsStream("/examples/example_ruins.nbt")) { + if (input == null) throw new IOException("Missing bundled example template"); + Files.copy(input, exampleTemplate); + } + } + Map output = new HashMap<>(); + Set names = new HashSet<>(); + Path definitions = root.resolve("definitions").toRealPath(); + try (var files = Files.list(definitions)) { + for (Path file : files.filter(p -> p.getFileName().toString().endsWith(".json")).sorted().toList()) { + try { + if (!file.toRealPath().startsWith(definitions)) throw new IOException("Definition symlink escapes directory"); + if (Files.size(file) > 1024 * 1024) throw new IOException("Definition exceeds 1 MiB"); + JsonObject json = JsonParser.parseString(Files.readString(file, StandardCharsets.UTF_8)).getAsJsonObject(); + StructureDefinition definition = StructureDefinition.parse(json); + if (!names.add(definition.name())) throw new IllegalArgumentException("Duplicate name: " + definition.name()); + Path template = definition.resolveTemplate(root.resolve("templates")); + if (Files.size(template) > 16 * 1024 * 1024) throw new IOException("Template exceeds 16 MiB"); + byte[] bytes = Files.readAllBytes(template); + validateTemplate(bytes); + addDefinition(output, definition, bytes); + } catch (IOException | RuntimeException exception) { + throw new IOException(file.getFileName() + ": " + exception.getMessage(), exception); + } + } + } + LogUtils.getLogger().info("Loaded {} configured Wild Wind structures from {}", names.size(), root); + return Map.copyOf(output); + } + + static void validateTemplate(byte[] bytes) throws IOException { + var nbt = NbtIo.readCompressed(new ByteArrayInputStream(bytes), NbtAccounter.create(64L * 1024 * 1024)); + var size = nbt.getListOrEmpty("size"); + if (size.size() != 3) throw new IOException("Template must have a three-component size"); + int x = size.getInt(0).orElse(0), y = size.getInt(1).orElse(0), z = size.getInt(2).orElse(0); + if (x < 1 || x > 64 || z < 1 || z > 64 || y < 1 || y > 256) { + throw new IOException("Template size must be within 64 x 256 x 64"); + } + var blocks = nbt.getListOrEmpty("blocks"); + var palettes = nbt.getListOrEmpty("palettes"); + var palette = nbt.getListOrEmpty("palette"); + if (!palettes.isEmpty()) palette = palettes.getList(0).orElseThrow(() -> new IOException("Invalid palettes list")); + if (blocks.isEmpty() || palette.isEmpty()) { + throw new IOException("Template must contain blocks and palette/palettes (compressed structure NBT required)"); + } + int paletteSize = palette.size(); + validatePalette(palette); + for (int i = 0; i < palettes.size(); i++) { + var variant = palettes.getList(i).orElseThrow(() -> new IOException("Invalid palette variant")); + if (variant.size() != paletteSize) throw new IOException("Palette variants must have equal length"); + validatePalette(variant); + } + for (int i = 0; i < blocks.size(); i++) { + var block = blocks.getCompound(i).orElseThrow(() -> new IOException("Invalid block entry")); + int state = block.getIntOr("state", -1); + var pos = block.getListOrEmpty("pos"); + if (state < 0 || state >= paletteSize || pos.size() != 3) throw new IOException("Invalid block state index or position"); + int px = pos.getInt(0).orElse(-1), py = pos.getInt(1).orElse(-1), pz = pos.getInt(2).orElse(-1); + if (px < 0 || px >= x || py < 0 || py >= y || pz < 0 || pz >= z) { + throw new IOException("Block position lies outside template size"); + } + } + } + + private static void validatePalette(net.minecraft.nbt.ListTag palette) throws IOException { + for (int i = 0; i < palette.size(); i++) { + var state = palette.getCompound(i).orElseThrow(() -> new IOException("Invalid palette entry")); + String name = state.getStringOr("Name", ""); + if (!name.contains(":") || Identifier.tryParse(name) == null) throw new IOException("Invalid palette block ID: " + name); + } + } + + static void addDefinition(Map output, StructureDefinition definition, byte[] template) { + String name = definition.name(); + String id = StructureModule.NAMESPACE + ":" + name; + JsonObject structure = new JsonObject(); + structure.addProperty("type", StructureModule.NAMESPACE + ":configured"); + structure.addProperty("biomes", "#" + id); + structure.add("spawn_overrides", new JsonObject()); + structure.addProperty("step", "surface_structures"); + structure.addProperty("terrain_adaptation", "none"); + structure.addProperty("template", id); + structure.addProperty("heightmap", definition.heightmap()); + structure.addProperty("y_offset", definition.yOffset()); + structure.addProperty("rotation", definition.rotation()); + structure.addProperty("include_entities", definition.includeEntities()); + structure.addProperty("min_y", definition.conditions().minY()); + structure.addProperty("max_y", definition.conditions().maxY()); + structure.addProperty("max_terrain_difference", definition.conditions().maxTerrainDifference()); + structure.addProperty("avoid_fluids", definition.conditions().avoidFluids()); + if (definition.conditions().groundBlocks().isEmpty()) structure.add("ground_blocks", new JsonArray()); + else { + structure.addProperty("ground_blocks", "#" + id); + putJson(output, "tags/block/" + name + ".json", tag(definition.conditions().groundBlocks())); + } + putJson(output, "worldgen/structure/" + name + ".json", structure); + putJson(output, "tags/worldgen/biome/" + name + ".json", tag(definition.biomes())); + output.put(resource("structure/" + name + ".nbt"), template); + // Keep disabled structures and templates registered so existing chunk starts remain readable. + if (!definition.enabled()) return; + JsonObject set = new JsonObject(); + JsonArray entries = new JsonArray(); + JsonObject entry = new JsonObject(); + entry.addProperty("structure", id); + entry.addProperty("weight", 1); + entries.add(entry); + set.add("structures", entries); + JsonObject placement = new JsonObject(); + placement.addProperty("type", "minecraft:random_spread"); + placement.addProperty("spacing", definition.spacing()); + placement.addProperty("separation", definition.separation()); + placement.addProperty("salt", definition.salt()); + placement.addProperty("frequency", definition.frequency()); + placement.addProperty("frequency_reduction_method", "default"); + placement.addProperty("spread_type", "linear"); + set.add("placement", placement); + putJson(output, "worldgen/structure_set/" + name + ".json", set); + } + + private static JsonObject tag(java.util.List values) { + JsonObject tag = new JsonObject(); + tag.addProperty("replace", false); + tag.add("values", JSON.toJsonTree(values)); + return tag; + } + + private static Identifier resource(String path) { return Identifier.fromNamespaceAndPath(StructureModule.NAMESPACE, path); } + private static void putJson(Map output, String path, JsonObject json) { + output.put(resource(path), JSON.toJson(json).getBytes(StandardCharsets.UTF_8)); + } + + @Override public Set getNamespaces(PackType type) { + return type == PackType.SERVER_DATA ? Set.of(StructureModule.NAMESPACE) : Set.of(); + } + @Override public IoSupplier getResource(PackType type, Identifier location) { + byte[] bytes = type == PackType.SERVER_DATA ? resources.get(location) : null; + return bytes == null ? null : () -> new ByteArrayInputStream(bytes); + } + @Override public void listResources(PackType type, String namespace, String path, ResourceOutput output) { + if (type != PackType.SERVER_DATA) return; + resources.forEach((id, bytes) -> { + if (id.getNamespace().equals(namespace) && id.getPath().startsWith(path + "/")) { + output.accept(id, () -> new ByteArrayInputStream(bytes)); + } + }); + } +} diff --git a/src/core/java/org/polaris2023/wildwind/structures/config/StructureDefinition.java b/src/core/java/org/polaris2023/wildwind/structures/config/StructureDefinition.java new file mode 100644 index 0000000..88dc35c --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/structures/config/StructureDefinition.java @@ -0,0 +1,135 @@ +package org.polaris2023.wildwind.structures.config; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +/** Validated user configuration. Registry and template validation happens when building the pack. */ +public record StructureDefinition(String name, boolean enabled, String template, List biomes, + int spacing, int separation, int salt, double frequency, String heightmap, + int yOffset, String rotation, boolean includeEntities, Conditions conditions) { + public record Conditions(int minY, int maxY, int maxTerrainDifference, + boolean avoidFluids, List groundBlocks) {} + + public static StructureDefinition parse(JsonObject json) { + keys(json, Set.of("name", "enabled", "template", "biomes", "placement", "heightmap", + "y_offset", "rotation", "include_entities", "conditions")); + String name = string(json, "name", null); + if (!name.matches("[a-z0-9_][a-z0-9_-]{0,63}")) { + throw new IllegalArgumentException("name must match [a-z0-9_][a-z0-9_-]{0,63}"); + } + String template = string(json, "template", null); + if (!template.endsWith(".nbt")) throw new IllegalArgumentException("template must end with .nbt"); + List biomes = identifiers(json, "biomes"); + if (biomes.isEmpty()) throw new IllegalArgumentException("biomes must not be empty"); + JsonObject placement = object(json, "placement"); + keys(placement, Set.of("spacing", "separation", "salt", "frequency")); + int spacing = integer(placement, "spacing", 32, 1, 4096); + int separation = integer(placement, "separation", 8, 0, 4095); + if (separation >= spacing) throw new IllegalArgumentException("separation must be smaller than spacing"); + int salt = integer(placement, "salt", name.hashCode() & Integer.MAX_VALUE, 0, Integer.MAX_VALUE); + double frequency = number(placement, "frequency", 1.0); + if (!Double.isFinite(frequency) || frequency <= 0 || frequency > 1) { + throw new IllegalArgumentException("frequency must be > 0 and <= 1 (use enabled=false to disable)"); + } + String heightmap = string(json, "heightmap", "WORLD_SURFACE_WG"); + if (!Set.of("WORLD_SURFACE_WG", "OCEAN_FLOOR_WG").contains(heightmap)) { + throw new IllegalArgumentException("heightmap must be WORLD_SURFACE_WG or OCEAN_FLOOR_WG"); + } + String rotation = string(json, "rotation", "random"); + if (!Set.of("random", "none", "clockwise_90", "clockwise_180", "counterclockwise_90").contains(rotation)) { + throw new IllegalArgumentException("unsupported rotation: " + rotation); + } + JsonObject conditions = object(json, "conditions"); + keys(conditions, Set.of("min_y", "max_y", "max_terrain_difference", "avoid_fluids", "ground_blocks")); + int minY = integer(conditions, "min_y", -64, -2032, 2031); + int maxY = integer(conditions, "max_y", 320, -2032, 2031); + if (minY > maxY) throw new IllegalArgumentException("min_y must be <= max_y"); + return new StructureDefinition(name, bool(json, "enabled", true), template, biomes, spacing, separation, salt, frequency, + heightmap, integer(json, "y_offset", 0, -256, 256), rotation, + bool(json, "include_entities", false), + new Conditions(minY, maxY, integer(conditions, "max_terrain_difference", 8, 0, 512), + bool(conditions, "avoid_fluids", true), identifiers(conditions, "ground_blocks"))); + } + + /** Both lexical traversal and symlink escapes are rejected. */ + public Path resolveTemplate(Path directory) throws java.io.IOException { + Path root = directory.toRealPath(); + Path relative = Path.of(template); + if (relative.isAbsolute() || template.contains("\\") || template.contains(":")) { + throw new IllegalArgumentException("template must be a relative path using /"); + } + Path candidate = root.resolve(relative).normalize(); + if (!candidate.startsWith(root)) throw new IllegalArgumentException("template escapes templates directory"); + Path real = candidate.toRealPath(); + if (!real.startsWith(root)) throw new IllegalArgumentException("template symlink escapes templates directory"); + return real; + } + + public static boolean bool(JsonObject object, String key, boolean fallback) { + if (!object.has(key)) return fallback; + JsonElement value = object.get(key); + if (!value.isJsonPrimitive() || !value.getAsJsonPrimitive().isBoolean()) { + throw new IllegalArgumentException(key + " must be a boolean"); + } + return value.getAsBoolean(); + } + + private static void keys(JsonObject object, Set allowed) { + for (String key : object.keySet()) { + if (!allowed.contains(key)) throw new IllegalArgumentException("unknown option: " + key); + } + } + + private static JsonObject object(JsonObject parent, String key) { + if (!parent.has(key)) return new JsonObject(); + if (!parent.get(key).isJsonObject()) throw new IllegalArgumentException(key + " must be an object"); + return parent.getAsJsonObject(key); + } + + private static String string(JsonObject object, String key, String fallback) { + if (!object.has(key)) { + if (fallback == null) throw new IllegalArgumentException("missing option: " + key); + return fallback; + } + JsonElement value = object.get(key); + if (!value.isJsonPrimitive() || !value.getAsJsonPrimitive().isString()) { + throw new IllegalArgumentException(key + " must be a string"); + } + return value.getAsString(); + } + + private static double number(JsonObject object, String key, double fallback) { + if (!object.has(key)) return fallback; + JsonElement value = object.get(key); + if (!value.isJsonPrimitive() || !value.getAsJsonPrimitive().isNumber()) { + throw new IllegalArgumentException(key + " must be a number"); + } + return value.getAsDouble(); + } + + private static int integer(JsonObject object, String key, int fallback, int min, int max) { + double value = number(object, key, fallback); + if (!Double.isFinite(value) || value != Math.rint(value) || value < min || value > max) { + throw new IllegalArgumentException(key + " must be an integer in [" + min + ", " + max + "]"); + } + return (int) value; + } + + private static List identifiers(JsonObject object, String key) { + if (!object.has(key)) return List.of(); + if (!object.get(key).isJsonArray()) throw new IllegalArgumentException(key + " must be an array"); + List values = new ArrayList<>(); + for (JsonElement entry : object.getAsJsonArray(key)) { + if (!entry.isJsonPrimitive() || !entry.getAsJsonPrimitive().isString() + || !entry.getAsString().matches("#?[a-z0-9_.-]+:[a-z0-9/._-]+")) { + throw new IllegalArgumentException(key + " entries must be namespaced IDs or #tags"); + } + values.add(entry.getAsString()); + } + return List.copyOf(values); + } +} diff --git a/src/core/java/org/polaris2023/wildwind/structures/worldgen/ConfiguredStructure.java b/src/core/java/org/polaris2023/wildwind/structures/worldgen/ConfiguredStructure.java new file mode 100644 index 0000000..850305b --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/structures/worldgen/ConfiguredStructure.java @@ -0,0 +1,111 @@ +package org.polaris2023.wildwind.structures.worldgen; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import java.util.Optional; +import net.minecraft.core.BlockPos; +import net.minecraft.core.HolderSet; +import net.minecraft.core.RegistryCodecs; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.Identifier; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Mirror; +import net.minecraft.world.level.block.Rotation; +import net.minecraft.world.level.levelgen.Heightmap; +import net.minecraft.world.level.levelgen.structure.Structure; +import net.minecraft.world.level.levelgen.structure.StructureType; +import org.polaris2023.wildwind.structures.StructureModule; + +public final class ConfiguredStructure extends Structure { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + settingsCodec(instance), + Identifier.CODEC.fieldOf("template").forGetter(s -> s.template), + Heightmap.Types.CODEC.fieldOf("heightmap").forGetter(s -> s.heightmap), + Codec.intRange(-256, 256).fieldOf("y_offset").forGetter(s -> s.yOffset), + Codec.STRING.fieldOf("rotation").forGetter(s -> s.rotation), + Codec.BOOL.fieldOf("include_entities").forGetter(s -> s.includeEntities), + Codec.INT.fieldOf("min_y").forGetter(s -> s.minY), + Codec.INT.fieldOf("max_y").forGetter(s -> s.maxY), + Codec.intRange(0, 512).fieldOf("max_terrain_difference").forGetter(s -> s.maxTerrainDifference), + Codec.BOOL.fieldOf("avoid_fluids").forGetter(s -> s.avoidFluids), + RegistryCodecs.homogeneousList(Registries.BLOCK).fieldOf("ground_blocks").forGetter(s -> s.groundBlocks) + ).apply(instance, ConfiguredStructure::new)); + + private final Identifier template; + private final Heightmap.Types heightmap; + private final int yOffset; + private final String rotation; + private final boolean includeEntities; + private final int minY, maxY, maxTerrainDifference; + private final boolean avoidFluids; + private final HolderSet groundBlocks; + + public ConfiguredStructure(StructureSettings settings, Identifier template, Heightmap.Types heightmap, + int yOffset, String rotation, boolean includeEntities, int minY, int maxY, + int maxTerrainDifference, boolean avoidFluids, HolderSet groundBlocks) { + super(settings); + this.template = template; + this.heightmap = heightmap; + this.yOffset = yOffset; + this.rotation = rotation; + this.includeEntities = includeEntities; + this.minY = minY; + this.maxY = maxY; + this.maxTerrainDifference = maxTerrainDifference; + this.avoidFluids = avoidFluids; + this.groundBlocks = groundBlocks; + } + + @Override protected Optional findGenerationPoint(GenerationContext context) { + var loaded = context.structureTemplateManager().get(template); + if (loaded.isEmpty()) return Optional.empty(); + var structureTemplate = loaded.get(); + Rotation chosenRotation = rotation.equals("random") ? Rotation.getRandom(context.random()) : rotation(rotation); + var size = structureTemplate.getSize(chosenRotation); + if (size.getX() < 1 || size.getZ() < 1 || size.getY() < 1 + || size.getX() > 64 || size.getZ() > 64 || size.getY() > 256) return Optional.empty(); + int centerX = context.chunkPos().getMiddleBlockX(), centerZ = context.chunkPos().getMiddleBlockZ(); + int left = centerX - size.getX() / 2, front = centerZ - size.getZ() / 2; + int right = left + size.getX() - 1, back = front + size.getZ() - 1; + // Sample four corners and the center before surface decoration. No adjacent chunks are loaded. + int[][] samples = {{left, front}, {right, front}, {left, back}, {right, back}, {centerX, centerZ}}; + int lowest = Integer.MAX_VALUE, highest = Integer.MIN_VALUE, centerHeight = 0; + for (int[] sample : samples) { + int height = context.chunkGenerator().getFirstFreeHeight(sample[0], sample[1], heightmap, + context.heightAccessor(), context.randomState()); + if (height < minY || height > maxY) return Optional.empty(); + lowest = Math.min(lowest, height); + highest = Math.max(highest, height); + centerHeight = height; + var column = context.chunkGenerator().getBaseColumn(sample[0], sample[1], context.heightAccessor(), context.randomState()); + var ground = column.getBlock(height - 1); + if (avoidFluids && (!ground.getFluidState().isEmpty() || !column.getBlock(height).getFluidState().isEmpty())) { + return Optional.empty(); + } + if (groundBlocks.size() > 0 && !groundBlocks.contains(ground.typeHolder())) return Optional.empty(); + } + if (highest - lowest > maxTerrainDifference) return Optional.empty(); + int y = centerHeight + yOffset; + if (y < context.heightAccessor().getMinY() || y + size.getY() > context.heightAccessor().getMaxY() + 1) { + return Optional.empty(); + } + BlockPos corner = new BlockPos(left, y, front); + BlockPos origin = structureTemplate.getZeroPositionWithTransform(corner, Mirror.NONE, chosenRotation); + BlockPos locatePosition = new BlockPos(centerX, y, centerZ); + return Optional.of(new GenerationStub(locatePosition, builder -> builder.addPiece( + new ConfiguredTemplatePiece(context.structureTemplateManager(), template, origin, chosenRotation, includeEntities)))); + } + + static Rotation rotation(String name) { + return switch (name) { + case "none" -> Rotation.NONE; + case "clockwise_90" -> Rotation.CLOCKWISE_90; + case "clockwise_180" -> Rotation.CLOCKWISE_180; + case "counterclockwise_90" -> Rotation.COUNTERCLOCKWISE_90; + default -> throw new IllegalArgumentException("Unknown structure rotation: " + name); + }; + } + + @Override public StructureType type() { return StructureModule.STRUCTURE.get(); } +} diff --git a/src/core/java/org/polaris2023/wildwind/structures/worldgen/ConfiguredTemplatePiece.java b/src/core/java/org/polaris2023/wildwind/structures/worldgen/ConfiguredTemplatePiece.java new file mode 100644 index 0000000..c8167ee --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/structures/worldgen/ConfiguredTemplatePiece.java @@ -0,0 +1,44 @@ +package org.polaris2023.wildwind.structures.worldgen; + +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.resources.Identifier; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.ServerLevelAccessor; +import net.minecraft.world.level.block.Rotation; +import net.minecraft.world.level.levelgen.structure.BoundingBox; +import net.minecraft.world.level.levelgen.structure.TemplateStructurePiece; +import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceSerializationContext; +import net.minecraft.world.level.levelgen.structure.templatesystem.BlockIgnoreProcessor; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager; +import org.polaris2023.wildwind.structures.StructureModule; + +/** Vanilla pieces clip blocks/entities to each generating chunk and persist template/rotation. */ +public final class ConfiguredTemplatePiece extends TemplateStructurePiece { + public ConfiguredTemplatePiece(StructureTemplateManager manager, Identifier template, BlockPos position, + Rotation rotation, boolean includeEntities) { + super(StructureModule.PIECE.get(), 0, manager, template, template.toString(), settings(rotation, includeEntities), position); + } + + public ConfiguredTemplatePiece(StructurePieceSerializationContext context, CompoundTag tag) { + super(StructureModule.PIECE.get(), tag, context.structureTemplateManager(), + id -> settings(Rotation.valueOf(tag.getStringOr("Rotation", "NONE")), tag.getBooleanOr("IncludeEntities", false))); + } + + private static StructurePlaceSettings settings(Rotation rotation, boolean includeEntities) { + return new StructurePlaceSettings().setRotation(rotation).setIgnoreEntities(!includeEntities) + .addProcessor(BlockIgnoreProcessor.STRUCTURE_BLOCK); + } + + @Override protected void addAdditionalSaveData(StructurePieceSerializationContext context, CompoundTag tag) { + super.addAdditionalSaveData(context, tag); + tag.putString("Rotation", placeSettings.getRotation().name()); + tag.putBoolean("IncludeEntities", !placeSettings.isIgnoreEntities()); + } + + @Override protected void handleDataMarker(String marker, BlockPos position, ServerLevelAccessor level, + RandomSource random, BoundingBox bounds) { + // Custom DATA markers are intentionally not interpreted; structure blocks are filtered out. + } +} diff --git a/src/core/java/org/polaris2023/wildwind/structures/worldgen/GeneratedStructureIndex.java b/src/core/java/org/polaris2023/wildwind/structures/worldgen/GeneratedStructureIndex.java new file mode 100644 index 0000000..2c2283a --- /dev/null +++ b/src/core/java/org/polaris2023/wildwind/structures/worldgen/GeneratedStructureIndex.java @@ -0,0 +1,69 @@ +package org.polaris2023.wildwind.structures.worldgen; + +import com.mojang.serialization.Codec; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import net.minecraft.core.BlockPos; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.Identifier; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.saveddata.SavedData; +import net.minecraft.world.level.saveddata.SavedDataType; +import net.neoforged.neoforge.event.level.ChunkEvent; +import org.polaris2023.wildwind.structures.StructureModule; + +/** Per-dimension index; only full chunks actually loaded into a world are recorded. */ +public final class GeneratedStructureIndex extends SavedData { + public static final Codec CODEC = Codec.unboundedMap(Identifier.CODEC, BlockPos.CODEC.listOf()) + .xmap(GeneratedStructureIndex::new, GeneratedStructureIndex::snapshot); + public static final SavedDataType TYPE = new SavedDataType<>( + Identifier.fromNamespaceAndPath(StructureModule.NAMESPACE, "generated_structures"), GeneratedStructureIndex::new, CODEC); + private final Map> positions = new HashMap<>(); + + public GeneratedStructureIndex() {} + private GeneratedStructureIndex(Map> saved) { + saved.forEach((id, list) -> positions.put(id, new HashSet<>(list))); + } + private Map> snapshot() { + Map> result = new HashMap<>(); + positions.forEach((id, values) -> result.put(id, new ArrayList<>(values))); + return result; + } + public void record(Identifier id, BlockPos position) { + if (positions.computeIfAbsent(id, ignored -> new HashSet<>()).add(position.immutable())) setDirty(); + } + public Set names() { return Set.copyOf(positions.keySet()); } + public Optional nearest(Identifier id, BlockPos from) { + return positions.getOrDefault(id, Set.of()).stream().min(Comparator + .comparingDouble((BlockPos p) -> horizontalDistanceSquared(p, from)) + .thenComparingInt(BlockPos::getX).thenComparingInt(BlockPos::getZ).thenComparingInt(BlockPos::getY)); + } + public static double horizontalDistanceSquared(BlockPos a, BlockPos b) { + double x = (double) a.getX() - b.getX(), z = (double) a.getZ() - b.getZ(); + return x * x + z * z; + } + + public static void onChunkLoad(ChunkEvent.Load event) { + if (!(event.getLevel() instanceof ServerLevel level)) return; + var registry = level.registryAccess().lookupOrThrow(Registries.STRUCTURE); + Map found = new HashMap<>(); + event.getChunk().getAllStarts().forEach((structure, start) -> { + if (!(structure instanceof ConfiguredStructure) || !start.isValid()) return; + Identifier id = registry.getKey(structure); + var bounds = start.getBoundingBox(); + if (id != null) found.put(id, new BlockPos(bounds.getCenter().getX(), bounds.minY(), bounds.getCenter().getZ())); + }); + if (found.isEmpty()) return; + // Do not touch SavedData or request chunks from the chunk-load callback. + level.getServer().execute(() -> { + var index = level.getDataStorage().computeIfAbsent(TYPE); + found.forEach(index::record); + }); + } +} diff --git a/src/core/resources/assets/wild_wind_core/blockstates/azalea_button.json b/src/core/resources/assets/wild_wind_core/blockstates/azalea_button.json new file mode 100644 index 0000000..187fabd --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/blockstates/azalea_button.json @@ -0,0 +1,118 @@ +{ + "variants": { + "face=ceiling,facing=east,powered=false": { + "model": "wild_wind_core:block/azalea_button", + "x": 180, + "y": 270 + }, + "face=ceiling,facing=east,powered=true": { + "model": "wild_wind_core:block/azalea_button_pressed", + "x": 180, + "y": 270 + }, + "face=ceiling,facing=north,powered=false": { + "model": "wild_wind_core:block/azalea_button", + "x": 180, + "y": 180 + }, + "face=ceiling,facing=north,powered=true": { + "model": "wild_wind_core:block/azalea_button_pressed", + "x": 180, + "y": 180 + }, + "face=ceiling,facing=south,powered=false": { + "model": "wild_wind_core:block/azalea_button", + "x": 180 + }, + "face=ceiling,facing=south,powered=true": { + "model": "wild_wind_core:block/azalea_button_pressed", + "x": 180 + }, + "face=ceiling,facing=west,powered=false": { + "model": "wild_wind_core:block/azalea_button", + "x": 180, + "y": 90 + }, + "face=ceiling,facing=west,powered=true": { + "model": "wild_wind_core:block/azalea_button_pressed", + "x": 180, + "y": 90 + }, + "face=floor,facing=east,powered=false": { + "model": "wild_wind_core:block/azalea_button", + "y": 90 + }, + "face=floor,facing=east,powered=true": { + "model": "wild_wind_core:block/azalea_button_pressed", + "y": 90 + }, + "face=floor,facing=north,powered=false": { + "model": "wild_wind_core:block/azalea_button" + }, + "face=floor,facing=north,powered=true": { + "model": "wild_wind_core:block/azalea_button_pressed" + }, + "face=floor,facing=south,powered=false": { + "model": "wild_wind_core:block/azalea_button", + "y": 180 + }, + "face=floor,facing=south,powered=true": { + "model": "wild_wind_core:block/azalea_button_pressed", + "y": 180 + }, + "face=floor,facing=west,powered=false": { + "model": "wild_wind_core:block/azalea_button", + "y": 270 + }, + "face=floor,facing=west,powered=true": { + "model": "wild_wind_core:block/azalea_button_pressed", + "y": 270 + }, + "face=wall,facing=east,powered=false": { + "model": "wild_wind_core:block/azalea_button", + "uvlock": true, + "x": 90, + "y": 90 + }, + "face=wall,facing=east,powered=true": { + "model": "wild_wind_core:block/azalea_button_pressed", + "uvlock": true, + "x": 90, + "y": 90 + }, + "face=wall,facing=north,powered=false": { + "model": "wild_wind_core:block/azalea_button", + "uvlock": true, + "x": 90 + }, + "face=wall,facing=north,powered=true": { + "model": "wild_wind_core:block/azalea_button_pressed", + "uvlock": true, + "x": 90 + }, + "face=wall,facing=south,powered=false": { + "model": "wild_wind_core:block/azalea_button", + "uvlock": true, + "x": 90, + "y": 180 + }, + "face=wall,facing=south,powered=true": { + "model": "wild_wind_core:block/azalea_button_pressed", + "uvlock": true, + "x": 90, + "y": 180 + }, + "face=wall,facing=west,powered=false": { + "model": "wild_wind_core:block/azalea_button", + "uvlock": true, + "x": 90, + "y": 270 + }, + "face=wall,facing=west,powered=true": { + "model": "wild_wind_core:block/azalea_button_pressed", + "uvlock": true, + "x": 90, + "y": 270 + } + } +} diff --git a/src/core/resources/assets/wild_wind_core/blockstates/azalea_door.json b/src/core/resources/assets/wild_wind_core/blockstates/azalea_door.json new file mode 100644 index 0000000..ff3e170 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/blockstates/azalea_door.json @@ -0,0 +1,124 @@ +{ + "variants": { + "facing=east,half=lower,hinge=left,open=false": { + "model": "wild_wind_core:block/azalea_door_bottom_left" + }, + "facing=east,half=lower,hinge=left,open=true": { + "model": "wild_wind_core:block/azalea_door_bottom_left_open", + "y": 90 + }, + "facing=east,half=lower,hinge=right,open=false": { + "model": "wild_wind_core:block/azalea_door_bottom_right" + }, + "facing=east,half=lower,hinge=right,open=true": { + "model": "wild_wind_core:block/azalea_door_bottom_right_open", + "y": 270 + }, + "facing=east,half=upper,hinge=left,open=false": { + "model": "wild_wind_core:block/azalea_door_top_left" + }, + "facing=east,half=upper,hinge=left,open=true": { + "model": "wild_wind_core:block/azalea_door_top_left_open", + "y": 90 + }, + "facing=east,half=upper,hinge=right,open=false": { + "model": "wild_wind_core:block/azalea_door_top_right" + }, + "facing=east,half=upper,hinge=right,open=true": { + "model": "wild_wind_core:block/azalea_door_top_right_open", + "y": 270 + }, + "facing=north,half=lower,hinge=left,open=false": { + "model": "wild_wind_core:block/azalea_door_bottom_left", + "y": 270 + }, + "facing=north,half=lower,hinge=left,open=true": { + "model": "wild_wind_core:block/azalea_door_bottom_left_open" + }, + "facing=north,half=lower,hinge=right,open=false": { + "model": "wild_wind_core:block/azalea_door_bottom_right", + "y": 270 + }, + "facing=north,half=lower,hinge=right,open=true": { + "model": "wild_wind_core:block/azalea_door_bottom_right_open", + "y": 180 + }, + "facing=north,half=upper,hinge=left,open=false": { + "model": "wild_wind_core:block/azalea_door_top_left", + "y": 270 + }, + "facing=north,half=upper,hinge=left,open=true": { + "model": "wild_wind_core:block/azalea_door_top_left_open" + }, + "facing=north,half=upper,hinge=right,open=false": { + "model": "wild_wind_core:block/azalea_door_top_right", + "y": 270 + }, + "facing=north,half=upper,hinge=right,open=true": { + "model": "wild_wind_core:block/azalea_door_top_right_open", + "y": 180 + }, + "facing=south,half=lower,hinge=left,open=false": { + "model": "wild_wind_core:block/azalea_door_bottom_left", + "y": 90 + }, + "facing=south,half=lower,hinge=left,open=true": { + "model": "wild_wind_core:block/azalea_door_bottom_left_open", + "y": 180 + }, + "facing=south,half=lower,hinge=right,open=false": { + "model": "wild_wind_core:block/azalea_door_bottom_right", + "y": 90 + }, + "facing=south,half=lower,hinge=right,open=true": { + "model": "wild_wind_core:block/azalea_door_bottom_right_open" + }, + "facing=south,half=upper,hinge=left,open=false": { + "model": "wild_wind_core:block/azalea_door_top_left", + "y": 90 + }, + "facing=south,half=upper,hinge=left,open=true": { + "model": "wild_wind_core:block/azalea_door_top_left_open", + "y": 180 + }, + "facing=south,half=upper,hinge=right,open=false": { + "model": "wild_wind_core:block/azalea_door_top_right", + "y": 90 + }, + "facing=south,half=upper,hinge=right,open=true": { + "model": "wild_wind_core:block/azalea_door_top_right_open" + }, + "facing=west,half=lower,hinge=left,open=false": { + "model": "wild_wind_core:block/azalea_door_bottom_left", + "y": 180 + }, + "facing=west,half=lower,hinge=left,open=true": { + "model": "wild_wind_core:block/azalea_door_bottom_left_open", + "y": 270 + }, + "facing=west,half=lower,hinge=right,open=false": { + "model": "wild_wind_core:block/azalea_door_bottom_right", + "y": 180 + }, + "facing=west,half=lower,hinge=right,open=true": { + "model": "wild_wind_core:block/azalea_door_bottom_right_open", + "y": 90 + }, + "facing=west,half=upper,hinge=left,open=false": { + "model": "wild_wind_core:block/azalea_door_top_left", + "y": 180 + }, + "facing=west,half=upper,hinge=left,open=true": { + "model": "wild_wind_core:block/azalea_door_top_left_open", + "y": 270 + }, + "facing=west,half=upper,hinge=right,open=false": { + "model": "wild_wind_core:block/azalea_door_top_right", + "y": 180 + }, + "facing=west,half=upper,hinge=right,open=true": { + "model": "wild_wind_core:block/azalea_door_top_right_open", + "y": 90 + } + } +} diff --git a/src/core/resources/assets/wild_wind_core/blockstates/azalea_fence.json b/src/core/resources/assets/wild_wind_core/blockstates/azalea_fence.json new file mode 100644 index 0000000..0df415f --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/blockstates/azalea_fence.json @@ -0,0 +1,48 @@ +{ + "multipart": [ + { + "apply": { + "model": "wild_wind_core:block/azalea_fence_post" + } + }, + { + "apply": { + "model": "wild_wind_core:block/azalea_fence_side", + "uvlock": true + }, + "when": { + "north": "true" + } + }, + { + "apply": { + "model": "wild_wind_core:block/azalea_fence_side", + "uvlock": true, + "y": 90 + }, + "when": { + "east": "true" + } + }, + { + "apply": { + "model": "wild_wind_core:block/azalea_fence_side", + "uvlock": true, + "y": 180 + }, + "when": { + "south": "true" + } + }, + { + "apply": { + "model": "wild_wind_core:block/azalea_fence_side", + "uvlock": true, + "y": 270 + }, + "when": { + "west": "true" + } + } + ] +} diff --git a/src/core/resources/assets/wild_wind_core/blockstates/azalea_fence_gate.json b/src/core/resources/assets/wild_wind_core/blockstates/azalea_fence_gate.json new file mode 100644 index 0000000..9d38076 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/blockstates/azalea_fence_gate.json @@ -0,0 +1,80 @@ +{ + "variants": { + "facing=east,in_wall=false,open=false": { + "model": "wild_wind_core:block/azalea_fence_gate", + "uvlock": true, + "y": 270 + }, + "facing=east,in_wall=false,open=true": { + "model": "wild_wind_core:block/azalea_fence_gate_open", + "uvlock": true, + "y": 270 + }, + "facing=east,in_wall=true,open=false": { + "model": "wild_wind_core:block/azalea_fence_gate_wall", + "uvlock": true, + "y": 270 + }, + "facing=east,in_wall=true,open=true": { + "model": "wild_wind_core:block/azalea_fence_gate_wall_open", + "uvlock": true, + "y": 270 + }, + "facing=north,in_wall=false,open=false": { + "model": "wild_wind_core:block/azalea_fence_gate", + "uvlock": true, + "y": 180 + }, + "facing=north,in_wall=false,open=true": { + "model": "wild_wind_core:block/azalea_fence_gate_open", + "uvlock": true, + "y": 180 + }, + "facing=north,in_wall=true,open=false": { + "model": "wild_wind_core:block/azalea_fence_gate_wall", + "uvlock": true, + "y": 180 + }, + "facing=north,in_wall=true,open=true": { + "model": "wild_wind_core:block/azalea_fence_gate_wall_open", + "uvlock": true, + "y": 180 + }, + "facing=south,in_wall=false,open=false": { + "model": "wild_wind_core:block/azalea_fence_gate", + "uvlock": true + }, + "facing=south,in_wall=false,open=true": { + "model": "wild_wind_core:block/azalea_fence_gate_open", + "uvlock": true + }, + "facing=south,in_wall=true,open=false": { + "model": "wild_wind_core:block/azalea_fence_gate_wall", + "uvlock": true + }, + "facing=south,in_wall=true,open=true": { + "model": "wild_wind_core:block/azalea_fence_gate_wall_open", + "uvlock": true + }, + "facing=west,in_wall=false,open=false": { + "model": "wild_wind_core:block/azalea_fence_gate", + "uvlock": true, + "y": 90 + }, + "facing=west,in_wall=false,open=true": { + "model": "wild_wind_core:block/azalea_fence_gate_open", + "uvlock": true, + "y": 90 + }, + "facing=west,in_wall=true,open=false": { + "model": "wild_wind_core:block/azalea_fence_gate_wall", + "uvlock": true, + "y": 90 + }, + "facing=west,in_wall=true,open=true": { + "model": "wild_wind_core:block/azalea_fence_gate_wall_open", + "uvlock": true, + "y": 90 + } + } +} diff --git a/src/core/resources/assets/wild_wind_core/blockstates/azalea_hanging_sign.json b/src/core/resources/assets/wild_wind_core/blockstates/azalea_hanging_sign.json new file mode 100644 index 0000000..8ca8732 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/blockstates/azalea_hanging_sign.json @@ -0,0 +1,124 @@ +{ + "variants": { + "attached=false,rotation=0": { + "model": "wild_wind_core:block/azalea_hanging_sign_rot_0" + }, + "attached=false,rotation=1": { + "model": "wild_wind_core:block/azalea_hanging_sign_rot_1" + }, + "attached=false,rotation=10": { + "model": "wild_wind_core:block/azalea_hanging_sign_rot_2", + "y": 180 + }, + "attached=false,rotation=11": { + "model": "wild_wind_core:block/azalea_hanging_sign_rot_3", + "y": 180 + }, + "attached=false,rotation=12": { + "model": "wild_wind_core:block/azalea_hanging_sign_rot_0", + "y": 270 + }, + "attached=false,rotation=13": { + "model": "wild_wind_core:block/azalea_hanging_sign_rot_1", + "y": 270 + }, + "attached=false,rotation=14": { + "model": "wild_wind_core:block/azalea_hanging_sign_rot_2", + "y": 270 + }, + "attached=false,rotation=15": { + "model": "wild_wind_core:block/azalea_hanging_sign_rot_3", + "y": 270 + }, + "attached=false,rotation=2": { + "model": "wild_wind_core:block/azalea_hanging_sign_rot_2" + }, + "attached=false,rotation=3": { + "model": "wild_wind_core:block/azalea_hanging_sign_rot_3" + }, + "attached=false,rotation=4": { + "model": "wild_wind_core:block/azalea_hanging_sign_rot_0", + "y": 90 + }, + "attached=false,rotation=5": { + "model": "wild_wind_core:block/azalea_hanging_sign_rot_1", + "y": 90 + }, + "attached=false,rotation=6": { + "model": "wild_wind_core:block/azalea_hanging_sign_rot_2", + "y": 90 + }, + "attached=false,rotation=7": { + "model": "wild_wind_core:block/azalea_hanging_sign_rot_3", + "y": 90 + }, + "attached=false,rotation=8": { + "model": "wild_wind_core:block/azalea_hanging_sign_rot_0", + "y": 180 + }, + "attached=false,rotation=9": { + "model": "wild_wind_core:block/azalea_hanging_sign_rot_1", + "y": 180 + }, + "attached=true,rotation=0": { + "model": "wild_wind_core:block/azalea_hanging_sign_attached_rot_0" + }, + "attached=true,rotation=1": { + "model": "wild_wind_core:block/azalea_hanging_sign_attached_rot_1" + }, + "attached=true,rotation=10": { + "model": "wild_wind_core:block/azalea_hanging_sign_attached_rot_2", + "y": 180 + }, + "attached=true,rotation=11": { + "model": "wild_wind_core:block/azalea_hanging_sign_attached_rot_3", + "y": 180 + }, + "attached=true,rotation=12": { + "model": "wild_wind_core:block/azalea_hanging_sign_attached_rot_0", + "y": 270 + }, + "attached=true,rotation=13": { + "model": "wild_wind_core:block/azalea_hanging_sign_attached_rot_1", + "y": 270 + }, + "attached=true,rotation=14": { + "model": "wild_wind_core:block/azalea_hanging_sign_attached_rot_2", + "y": 270 + }, + "attached=true,rotation=15": { + "model": "wild_wind_core:block/azalea_hanging_sign_attached_rot_3", + "y": 270 + }, + "attached=true,rotation=2": { + "model": "wild_wind_core:block/azalea_hanging_sign_attached_rot_2" + }, + "attached=true,rotation=3": { + "model": "wild_wind_core:block/azalea_hanging_sign_attached_rot_3" + }, + "attached=true,rotation=4": { + "model": "wild_wind_core:block/azalea_hanging_sign_attached_rot_0", + "y": 90 + }, + "attached=true,rotation=5": { + "model": "wild_wind_core:block/azalea_hanging_sign_attached_rot_1", + "y": 90 + }, + "attached=true,rotation=6": { + "model": "wild_wind_core:block/azalea_hanging_sign_attached_rot_2", + "y": 90 + }, + "attached=true,rotation=7": { + "model": "wild_wind_core:block/azalea_hanging_sign_attached_rot_3", + "y": 90 + }, + "attached=true,rotation=8": { + "model": "wild_wind_core:block/azalea_hanging_sign_attached_rot_0", + "y": 180 + }, + "attached=true,rotation=9": { + "model": "wild_wind_core:block/azalea_hanging_sign_attached_rot_1", + "y": 180 + } + } +} diff --git a/src/core/resources/assets/wild_wind_core/blockstates/azalea_log.json b/src/core/resources/assets/wild_wind_core/blockstates/azalea_log.json new file mode 100644 index 0000000..d946e87 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/blockstates/azalea_log.json @@ -0,0 +1,16 @@ +{ + "variants": { + "axis=x": { + "model": "wild_wind_core:block/azalea_log_horizontal", + "x": 90, + "y": 90 + }, + "axis=y": { + "model": "wild_wind_core:block/azalea_log" + }, + "axis=z": { + "model": "wild_wind_core:block/azalea_log_horizontal", + "x": 90 + } + } +} diff --git a/src/core/resources/assets/wild_wind_core/blockstates/azalea_planks.json b/src/core/resources/assets/wild_wind_core/blockstates/azalea_planks.json new file mode 100644 index 0000000..7ea3199 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/blockstates/azalea_planks.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "wild_wind_core:block/azalea_planks" + } + } +} diff --git a/src/core/resources/assets/wild_wind_core/blockstates/azalea_pressure_plate.json b/src/core/resources/assets/wild_wind_core/blockstates/azalea_pressure_plate.json new file mode 100644 index 0000000..549d59b --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/blockstates/azalea_pressure_plate.json @@ -0,0 +1,10 @@ +{ + "variants": { + "powered=false": { + "model": "wild_wind_core:block/azalea_pressure_plate" + }, + "powered=true": { + "model": "wild_wind_core:block/azalea_pressure_plate_down" + } + } +} diff --git a/src/core/resources/assets/wild_wind_core/blockstates/azalea_shelf.json b/src/core/resources/assets/wild_wind_core/blockstates/azalea_shelf.json new file mode 100644 index 0000000..13e87e8 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/blockstates/azalea_shelf.json @@ -0,0 +1,402 @@ +{ + "multipart": [ + { + "apply": { + "model": "wild_wind_core:block/azalea_shelf" + }, + "when": { + "facing": "north" + } + }, + { + "apply": { + "model": "wild_wind_core:block/azalea_shelf", + "y": 90 + }, + "when": { + "facing": "east" + } + }, + { + "apply": { + "model": "wild_wind_core:block/azalea_shelf", + "y": 180 + }, + "when": { + "facing": "south" + } + }, + { + "apply": { + "model": "wild_wind_core:block/azalea_shelf", + "y": 270 + }, + "when": { + "facing": "west" + } + }, + { + "apply": { + "model": "wild_wind_core:block/azalea_shelf_unpowered" + }, + "when": { + "AND": [ + { + "facing": "north" + }, + { + "powered": "false" + } + ] + } + }, + { + "apply": { + "model": "wild_wind_core:block/azalea_shelf_unpowered", + "y": 90 + }, + "when": { + "AND": [ + { + "facing": "east" + }, + { + "powered": "false" + } + ] + } + }, + { + "apply": { + "model": "wild_wind_core:block/azalea_shelf_unpowered", + "y": 180 + }, + "when": { + "AND": [ + { + "facing": "south" + }, + { + "powered": "false" + } + ] + } + }, + { + "apply": { + "model": "wild_wind_core:block/azalea_shelf_unpowered", + "y": 270 + }, + "when": { + "AND": [ + { + "facing": "west" + }, + { + "powered": "false" + } + ] + } + }, + { + "apply": { + "model": "wild_wind_core:block/azalea_shelf_unconnected" + }, + "when": { + "AND": [ + { + "facing": "north" + }, + { + "powered": "true" + }, + { + "side_chain": "unconnected" + } + ] + } + }, + { + "apply": { + "model": "wild_wind_core:block/azalea_shelf_unconnected", + "y": 90 + }, + "when": { + "AND": [ + { + "facing": "east" + }, + { + "powered": "true" + }, + { + "side_chain": "unconnected" + } + ] + } + }, + { + "apply": { + "model": "wild_wind_core:block/azalea_shelf_unconnected", + "y": 180 + }, + "when": { + "AND": [ + { + "facing": "south" + }, + { + "powered": "true" + }, + { + "side_chain": "unconnected" + } + ] + } + }, + { + "apply": { + "model": "wild_wind_core:block/azalea_shelf_unconnected", + "y": 270 + }, + "when": { + "AND": [ + { + "facing": "west" + }, + { + "powered": "true" + }, + { + "side_chain": "unconnected" + } + ] + } + }, + { + "apply": { + "model": "wild_wind_core:block/azalea_shelf_left" + }, + "when": { + "AND": [ + { + "facing": "north" + }, + { + "powered": "true" + }, + { + "side_chain": "left" + } + ] + } + }, + { + "apply": { + "model": "wild_wind_core:block/azalea_shelf_left", + "y": 90 + }, + "when": { + "AND": [ + { + "facing": "east" + }, + { + "powered": "true" + }, + { + "side_chain": "left" + } + ] + } + }, + { + "apply": { + "model": "wild_wind_core:block/azalea_shelf_left", + "y": 180 + }, + "when": { + "AND": [ + { + "facing": "south" + }, + { + "powered": "true" + }, + { + "side_chain": "left" + } + ] + } + }, + { + "apply": { + "model": "wild_wind_core:block/azalea_shelf_left", + "y": 270 + }, + "when": { + "AND": [ + { + "facing": "west" + }, + { + "powered": "true" + }, + { + "side_chain": "left" + } + ] + } + }, + { + "apply": { + "model": "wild_wind_core:block/azalea_shelf_center" + }, + "when": { + "AND": [ + { + "facing": "north" + }, + { + "powered": "true" + }, + { + "side_chain": "center" + } + ] + } + }, + { + "apply": { + "model": "wild_wind_core:block/azalea_shelf_center", + "y": 90 + }, + "when": { + "AND": [ + { + "facing": "east" + }, + { + "powered": "true" + }, + { + "side_chain": "center" + } + ] + } + }, + { + "apply": { + "model": "wild_wind_core:block/azalea_shelf_center", + "y": 180 + }, + "when": { + "AND": [ + { + "facing": "south" + }, + { + "powered": "true" + }, + { + "side_chain": "center" + } + ] + } + }, + { + "apply": { + "model": "wild_wind_core:block/azalea_shelf_center", + "y": 270 + }, + "when": { + "AND": [ + { + "facing": "west" + }, + { + "powered": "true" + }, + { + "side_chain": "center" + } + ] + } + }, + { + "apply": { + "model": "wild_wind_core:block/azalea_shelf_right" + }, + "when": { + "AND": [ + { + "facing": "north" + }, + { + "powered": "true" + }, + { + "side_chain": "right" + } + ] + } + }, + { + "apply": { + "model": "wild_wind_core:block/azalea_shelf_right", + "y": 90 + }, + "when": { + "AND": [ + { + "facing": "east" + }, + { + "powered": "true" + }, + { + "side_chain": "right" + } + ] + } + }, + { + "apply": { + "model": "wild_wind_core:block/azalea_shelf_right", + "y": 180 + }, + "when": { + "AND": [ + { + "facing": "south" + }, + { + "powered": "true" + }, + { + "side_chain": "right" + } + ] + } + }, + { + "apply": { + "model": "wild_wind_core:block/azalea_shelf_right", + "y": 270 + }, + "when": { + "AND": [ + { + "facing": "west" + }, + { + "powered": "true" + }, + { + "side_chain": "right" + } + ] + } + } + ] +} diff --git a/src/core/resources/assets/wild_wind_core/blockstates/azalea_sign.json b/src/core/resources/assets/wild_wind_core/blockstates/azalea_sign.json new file mode 100644 index 0000000..86b676a --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/blockstates/azalea_sign.json @@ -0,0 +1,64 @@ +{ + "variants": { + "rotation=0": { + "model": "wild_wind_core:block/azalea_sign_rot_0" + }, + "rotation=1": { + "model": "wild_wind_core:block/azalea_sign_rot_1" + }, + "rotation=10": { + "model": "wild_wind_core:block/azalea_sign_rot_2", + "y": 180 + }, + "rotation=11": { + "model": "wild_wind_core:block/azalea_sign_rot_3", + "y": 180 + }, + "rotation=12": { + "model": "wild_wind_core:block/azalea_sign_rot_0", + "y": 270 + }, + "rotation=13": { + "model": "wild_wind_core:block/azalea_sign_rot_1", + "y": 270 + }, + "rotation=14": { + "model": "wild_wind_core:block/azalea_sign_rot_2", + "y": 270 + }, + "rotation=15": { + "model": "wild_wind_core:block/azalea_sign_rot_3", + "y": 270 + }, + "rotation=2": { + "model": "wild_wind_core:block/azalea_sign_rot_2" + }, + "rotation=3": { + "model": "wild_wind_core:block/azalea_sign_rot_3" + }, + "rotation=4": { + "model": "wild_wind_core:block/azalea_sign_rot_0", + "y": 90 + }, + "rotation=5": { + "model": "wild_wind_core:block/azalea_sign_rot_1", + "y": 90 + }, + "rotation=6": { + "model": "wild_wind_core:block/azalea_sign_rot_2", + "y": 90 + }, + "rotation=7": { + "model": "wild_wind_core:block/azalea_sign_rot_3", + "y": 90 + }, + "rotation=8": { + "model": "wild_wind_core:block/azalea_sign_rot_0", + "y": 180 + }, + "rotation=9": { + "model": "wild_wind_core:block/azalea_sign_rot_1", + "y": 180 + } + } +} diff --git a/src/core/resources/assets/wild_wind_core/blockstates/azalea_slab.json b/src/core/resources/assets/wild_wind_core/blockstates/azalea_slab.json new file mode 100644 index 0000000..93e7436 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/blockstates/azalea_slab.json @@ -0,0 +1,13 @@ +{ + "variants": { + "type=bottom": { + "model": "wild_wind_core:block/azalea_slab" + }, + "type=double": { + "model": "wild_wind_core:block/azalea_planks" + }, + "type=top": { + "model": "wild_wind_core:block/azalea_slab_top" + } + } +} diff --git a/src/core/resources/assets/wild_wind_core/blockstates/azalea_stairs.json b/src/core/resources/assets/wild_wind_core/blockstates/azalea_stairs.json new file mode 100644 index 0000000..8575030 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/blockstates/azalea_stairs.json @@ -0,0 +1,209 @@ +{ + "variants": { + "facing=east,half=bottom,shape=inner_left": { + "model": "wild_wind_core:block/azalea_stairs_inner", + "uvlock": true, + "y": 270 + }, + "facing=east,half=bottom,shape=inner_right": { + "model": "wild_wind_core:block/azalea_stairs_inner" + }, + "facing=east,half=bottom,shape=outer_left": { + "model": "wild_wind_core:block/azalea_stairs_outer", + "uvlock": true, + "y": 270 + }, + "facing=east,half=bottom,shape=outer_right": { + "model": "wild_wind_core:block/azalea_stairs_outer" + }, + "facing=east,half=bottom,shape=straight": { + "model": "wild_wind_core:block/azalea_stairs" + }, + "facing=east,half=top,shape=inner_left": { + "model": "wild_wind_core:block/azalea_stairs_inner", + "uvlock": true, + "x": 180 + }, + "facing=east,half=top,shape=inner_right": { + "model": "wild_wind_core:block/azalea_stairs_inner", + "uvlock": true, + "x": 180, + "y": 90 + }, + "facing=east,half=top,shape=outer_left": { + "model": "wild_wind_core:block/azalea_stairs_outer", + "uvlock": true, + "x": 180 + }, + "facing=east,half=top,shape=outer_right": { + "model": "wild_wind_core:block/azalea_stairs_outer", + "uvlock": true, + "x": 180, + "y": 90 + }, + "facing=east,half=top,shape=straight": { + "model": "wild_wind_core:block/azalea_stairs", + "uvlock": true, + "x": 180 + }, + "facing=north,half=bottom,shape=inner_left": { + "model": "wild_wind_core:block/azalea_stairs_inner", + "uvlock": true, + "y": 180 + }, + "facing=north,half=bottom,shape=inner_right": { + "model": "wild_wind_core:block/azalea_stairs_inner", + "uvlock": true, + "y": 270 + }, + "facing=north,half=bottom,shape=outer_left": { + "model": "wild_wind_core:block/azalea_stairs_outer", + "uvlock": true, + "y": 180 + }, + "facing=north,half=bottom,shape=outer_right": { + "model": "wild_wind_core:block/azalea_stairs_outer", + "uvlock": true, + "y": 270 + }, + "facing=north,half=bottom,shape=straight": { + "model": "wild_wind_core:block/azalea_stairs", + "uvlock": true, + "y": 270 + }, + "facing=north,half=top,shape=inner_left": { + "model": "wild_wind_core:block/azalea_stairs_inner", + "uvlock": true, + "x": 180, + "y": 270 + }, + "facing=north,half=top,shape=inner_right": { + "model": "wild_wind_core:block/azalea_stairs_inner", + "uvlock": true, + "x": 180 + }, + "facing=north,half=top,shape=outer_left": { + "model": "wild_wind_core:block/azalea_stairs_outer", + "uvlock": true, + "x": 180, + "y": 270 + }, + "facing=north,half=top,shape=outer_right": { + "model": "wild_wind_core:block/azalea_stairs_outer", + "uvlock": true, + "x": 180 + }, + "facing=north,half=top,shape=straight": { + "model": "wild_wind_core:block/azalea_stairs", + "uvlock": true, + "x": 180, + "y": 270 + }, + "facing=south,half=bottom,shape=inner_left": { + "model": "wild_wind_core:block/azalea_stairs_inner" + }, + "facing=south,half=bottom,shape=inner_right": { + "model": "wild_wind_core:block/azalea_stairs_inner", + "uvlock": true, + "y": 90 + }, + "facing=south,half=bottom,shape=outer_left": { + "model": "wild_wind_core:block/azalea_stairs_outer" + }, + "facing=south,half=bottom,shape=outer_right": { + "model": "wild_wind_core:block/azalea_stairs_outer", + "uvlock": true, + "y": 90 + }, + "facing=south,half=bottom,shape=straight": { + "model": "wild_wind_core:block/azalea_stairs", + "uvlock": true, + "y": 90 + }, + "facing=south,half=top,shape=inner_left": { + "model": "wild_wind_core:block/azalea_stairs_inner", + "uvlock": true, + "x": 180, + "y": 90 + }, + "facing=south,half=top,shape=inner_right": { + "model": "wild_wind_core:block/azalea_stairs_inner", + "uvlock": true, + "x": 180, + "y": 180 + }, + "facing=south,half=top,shape=outer_left": { + "model": "wild_wind_core:block/azalea_stairs_outer", + "uvlock": true, + "x": 180, + "y": 90 + }, + "facing=south,half=top,shape=outer_right": { + "model": "wild_wind_core:block/azalea_stairs_outer", + "uvlock": true, + "x": 180, + "y": 180 + }, + "facing=south,half=top,shape=straight": { + "model": "wild_wind_core:block/azalea_stairs", + "uvlock": true, + "x": 180, + "y": 90 + }, + "facing=west,half=bottom,shape=inner_left": { + "model": "wild_wind_core:block/azalea_stairs_inner", + "uvlock": true, + "y": 90 + }, + "facing=west,half=bottom,shape=inner_right": { + "model": "wild_wind_core:block/azalea_stairs_inner", + "uvlock": true, + "y": 180 + }, + "facing=west,half=bottom,shape=outer_left": { + "model": "wild_wind_core:block/azalea_stairs_outer", + "uvlock": true, + "y": 90 + }, + "facing=west,half=bottom,shape=outer_right": { + "model": "wild_wind_core:block/azalea_stairs_outer", + "uvlock": true, + "y": 180 + }, + "facing=west,half=bottom,shape=straight": { + "model": "wild_wind_core:block/azalea_stairs", + "uvlock": true, + "y": 180 + }, + "facing=west,half=top,shape=inner_left": { + "model": "wild_wind_core:block/azalea_stairs_inner", + "uvlock": true, + "x": 180, + "y": 180 + }, + "facing=west,half=top,shape=inner_right": { + "model": "wild_wind_core:block/azalea_stairs_inner", + "uvlock": true, + "x": 180, + "y": 270 + }, + "facing=west,half=top,shape=outer_left": { + "model": "wild_wind_core:block/azalea_stairs_outer", + "uvlock": true, + "x": 180, + "y": 180 + }, + "facing=west,half=top,shape=outer_right": { + "model": "wild_wind_core:block/azalea_stairs_outer", + "uvlock": true, + "x": 180, + "y": 270 + }, + "facing=west,half=top,shape=straight": { + "model": "wild_wind_core:block/azalea_stairs", + "uvlock": true, + "x": 180, + "y": 180 + } + } +} diff --git a/src/core/resources/assets/wild_wind_core/blockstates/azalea_trapdoor.json b/src/core/resources/assets/wild_wind_core/blockstates/azalea_trapdoor.json new file mode 100644 index 0000000..eee8566 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/blockstates/azalea_trapdoor.json @@ -0,0 +1,58 @@ +{ + "variants": { + "facing=east,half=bottom,open=false": { + "model": "wild_wind_core:block/azalea_trapdoor_bottom" + }, + "facing=east,half=bottom,open=true": { + "model": "wild_wind_core:block/azalea_trapdoor_open", + "y": 90 + }, + "facing=east,half=top,open=false": { + "model": "wild_wind_core:block/azalea_trapdoor_top" + }, + "facing=east,half=top,open=true": { + "model": "wild_wind_core:block/azalea_trapdoor_open", + "y": 90 + }, + "facing=north,half=bottom,open=false": { + "model": "wild_wind_core:block/azalea_trapdoor_bottom" + }, + "facing=north,half=bottom,open=true": { + "model": "wild_wind_core:block/azalea_trapdoor_open" + }, + "facing=north,half=top,open=false": { + "model": "wild_wind_core:block/azalea_trapdoor_top" + }, + "facing=north,half=top,open=true": { + "model": "wild_wind_core:block/azalea_trapdoor_open" + }, + "facing=south,half=bottom,open=false": { + "model": "wild_wind_core:block/azalea_trapdoor_bottom" + }, + "facing=south,half=bottom,open=true": { + "model": "wild_wind_core:block/azalea_trapdoor_open", + "y": 180 + }, + "facing=south,half=top,open=false": { + "model": "wild_wind_core:block/azalea_trapdoor_top" + }, + "facing=south,half=top,open=true": { + "model": "wild_wind_core:block/azalea_trapdoor_open", + "y": 180 + }, + "facing=west,half=bottom,open=false": { + "model": "wild_wind_core:block/azalea_trapdoor_bottom" + }, + "facing=west,half=bottom,open=true": { + "model": "wild_wind_core:block/azalea_trapdoor_open", + "y": 270 + }, + "facing=west,half=top,open=false": { + "model": "wild_wind_core:block/azalea_trapdoor_top" + }, + "facing=west,half=top,open=true": { + "model": "wild_wind_core:block/azalea_trapdoor_open", + "y": 270 + } + } +} diff --git a/src/core/resources/assets/wild_wind_core/blockstates/azalea_wall_hanging_sign.json b/src/core/resources/assets/wild_wind_core/blockstates/azalea_wall_hanging_sign.json new file mode 100644 index 0000000..35ac0f4 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/blockstates/azalea_wall_hanging_sign.json @@ -0,0 +1,19 @@ +{ + "variants": { + "facing=east": { + "model": "wild_wind_core:block/azalea_wall_hanging_sign", + "y": 270 + }, + "facing=north": { + "model": "wild_wind_core:block/azalea_wall_hanging_sign", + "y": 180 + }, + "facing=south": { + "model": "wild_wind_core:block/azalea_wall_hanging_sign" + }, + "facing=west": { + "model": "wild_wind_core:block/azalea_wall_hanging_sign", + "y": 90 + } + } +} diff --git a/src/core/resources/assets/wild_wind_core/blockstates/azalea_wall_sign.json b/src/core/resources/assets/wild_wind_core/blockstates/azalea_wall_sign.json new file mode 100644 index 0000000..232cc2b --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/blockstates/azalea_wall_sign.json @@ -0,0 +1,19 @@ +{ + "variants": { + "facing=east": { + "model": "wild_wind_core:block/azalea_wall_sign", + "y": 270 + }, + "facing=north": { + "model": "wild_wind_core:block/azalea_wall_sign", + "y": 180 + }, + "facing=south": { + "model": "wild_wind_core:block/azalea_wall_sign" + }, + "facing=west": { + "model": "wild_wind_core:block/azalea_wall_sign", + "y": 90 + } + } +} diff --git a/src/core/resources/assets/wild_wind_core/blockstates/azalea_wood.json b/src/core/resources/assets/wild_wind_core/blockstates/azalea_wood.json new file mode 100644 index 0000000..a53c859 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/blockstates/azalea_wood.json @@ -0,0 +1,16 @@ +{ + "variants": { + "axis=x": { + "model": "wild_wind_core:block/azalea_wood", + "x": 90, + "y": 90 + }, + "axis=y": { + "model": "wild_wind_core:block/azalea_wood" + }, + "axis=z": { + "model": "wild_wind_core:block/azalea_wood", + "x": 90 + } + } +} diff --git a/src/core/resources/assets/wild_wind_core/blockstates/kiln.json b/src/core/resources/assets/wild_wind_core/blockstates/kiln.json new file mode 100644 index 0000000..b86d059 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/blockstates/kiln.json @@ -0,0 +1,34 @@ +{ + "variants": { + "facing=east,lit=false": { + "model": "minecraft:block/furnace", + "y": 90 + }, + "facing=east,lit=true": { + "model": "minecraft:block/furnace_on", + "y": 90 + }, + "facing=north,lit=false": { + "model": "minecraft:block/furnace" + }, + "facing=north,lit=true": { + "model": "minecraft:block/furnace_on" + }, + "facing=south,lit=false": { + "model": "minecraft:block/furnace", + "y": 180 + }, + "facing=south,lit=true": { + "model": "minecraft:block/furnace_on", + "y": 180 + }, + "facing=west,lit=false": { + "model": "minecraft:block/furnace", + "y": 270 + }, + "facing=west,lit=true": { + "model": "minecraft:block/furnace_on", + "y": 270 + } + } +} diff --git a/src/core/resources/assets/wild_wind_core/blockstates/stripped_azalea_log.json b/src/core/resources/assets/wild_wind_core/blockstates/stripped_azalea_log.json new file mode 100644 index 0000000..4dbdb64 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/blockstates/stripped_azalea_log.json @@ -0,0 +1,16 @@ +{ + "variants": { + "axis=x": { + "model": "wild_wind_core:block/stripped_azalea_log_horizontal", + "x": 90, + "y": 90 + }, + "axis=y": { + "model": "wild_wind_core:block/stripped_azalea_log" + }, + "axis=z": { + "model": "wild_wind_core:block/stripped_azalea_log_horizontal", + "x": 90 + } + } +} diff --git a/src/core/resources/assets/wild_wind_core/blockstates/stripped_azalea_wood.json b/src/core/resources/assets/wild_wind_core/blockstates/stripped_azalea_wood.json new file mode 100644 index 0000000..bf07c6e --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/blockstates/stripped_azalea_wood.json @@ -0,0 +1,16 @@ +{ + "variants": { + "axis=x": { + "model": "wild_wind_core:block/stripped_azalea_wood", + "x": 90, + "y": 90 + }, + "axis=y": { + "model": "wild_wind_core:block/stripped_azalea_wood" + }, + "axis=z": { + "model": "wild_wind_core:block/stripped_azalea_wood", + "x": 90 + } + } +} diff --git a/src/core/resources/assets/wild_wind_core/items/azalea_boat.json b/src/core/resources/assets/wild_wind_core/items/azalea_boat.json new file mode 100644 index 0000000..37a486e --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/items/azalea_boat.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_core:item/azalea_boat" + } +} \ No newline at end of file diff --git a/src/core/resources/assets/wild_wind_core/items/azalea_button.json b/src/core/resources/assets/wild_wind_core/items/azalea_button.json new file mode 100644 index 0000000..07890a1 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/items/azalea_button.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_core:block/azalea_button_inventory" + } +} diff --git a/src/core/resources/assets/wild_wind_core/items/azalea_chest_boat.json b/src/core/resources/assets/wild_wind_core/items/azalea_chest_boat.json new file mode 100644 index 0000000..1dd4332 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/items/azalea_chest_boat.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_core:item/azalea_chest_boat" + } +} \ No newline at end of file diff --git a/src/core/resources/assets/wild_wind_core/items/azalea_door.json b/src/core/resources/assets/wild_wind_core/items/azalea_door.json new file mode 100644 index 0000000..b99b76a --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/items/azalea_door.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_core:item/azalea_door" + } +} diff --git a/src/core/resources/assets/wild_wind_core/items/azalea_fence.json b/src/core/resources/assets/wild_wind_core/items/azalea_fence.json new file mode 100644 index 0000000..5a0e2f3 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/items/azalea_fence.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_core:block/azalea_fence_inventory" + } +} diff --git a/src/core/resources/assets/wild_wind_core/items/azalea_fence_gate.json b/src/core/resources/assets/wild_wind_core/items/azalea_fence_gate.json new file mode 100644 index 0000000..4a186c6 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/items/azalea_fence_gate.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_core:block/azalea_fence_gate" + } +} diff --git a/src/core/resources/assets/wild_wind_core/items/azalea_hanging_sign.json b/src/core/resources/assets/wild_wind_core/items/azalea_hanging_sign.json new file mode 100644 index 0000000..1412d39 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/items/azalea_hanging_sign.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_core:item/azalea_hanging_sign" + } +} diff --git a/src/core/resources/assets/wild_wind_core/items/azalea_log.json b/src/core/resources/assets/wild_wind_core/items/azalea_log.json new file mode 100644 index 0000000..3100539 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/items/azalea_log.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_core:block/azalea_log" + } +} diff --git a/src/core/resources/assets/wild_wind_core/items/azalea_planks.json b/src/core/resources/assets/wild_wind_core/items/azalea_planks.json new file mode 100644 index 0000000..79f251b --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/items/azalea_planks.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_core:block/azalea_planks" + } +} diff --git a/src/core/resources/assets/wild_wind_core/items/azalea_pressure_plate.json b/src/core/resources/assets/wild_wind_core/items/azalea_pressure_plate.json new file mode 100644 index 0000000..523f757 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/items/azalea_pressure_plate.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_core:block/azalea_pressure_plate" + } +} diff --git a/src/core/resources/assets/wild_wind_core/items/azalea_shelf.json b/src/core/resources/assets/wild_wind_core/items/azalea_shelf.json new file mode 100644 index 0000000..63d07d8 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/items/azalea_shelf.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_core:block/azalea_shelf_inventory" + } +} diff --git a/src/core/resources/assets/wild_wind_core/items/azalea_sign.json b/src/core/resources/assets/wild_wind_core/items/azalea_sign.json new file mode 100644 index 0000000..677fc1c --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/items/azalea_sign.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_core:item/azalea_sign" + } +} diff --git a/src/core/resources/assets/wild_wind_core/items/azalea_slab.json b/src/core/resources/assets/wild_wind_core/items/azalea_slab.json new file mode 100644 index 0000000..3e9e0be --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/items/azalea_slab.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_core:block/azalea_slab" + } +} diff --git a/src/core/resources/assets/wild_wind_core/items/azalea_stairs.json b/src/core/resources/assets/wild_wind_core/items/azalea_stairs.json new file mode 100644 index 0000000..09499e0 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/items/azalea_stairs.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_core:block/azalea_stairs" + } +} diff --git a/src/core/resources/assets/wild_wind_core/items/azalea_trapdoor.json b/src/core/resources/assets/wild_wind_core/items/azalea_trapdoor.json new file mode 100644 index 0000000..1471053 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/items/azalea_trapdoor.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_core:block/azalea_trapdoor_bottom" + } +} diff --git a/src/core/resources/assets/wild_wind_core/items/azalea_wood.json b/src/core/resources/assets/wild_wind_core/items/azalea_wood.json new file mode 100644 index 0000000..08feb64 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/items/azalea_wood.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_core:block/azalea_wood" + } +} diff --git a/src/core/resources/assets/wild_wind_core/items/baked_seeds.json b/src/core/resources/assets/wild_wind_core/items/baked_seeds.json new file mode 100644 index 0000000..91da65f --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/items/baked_seeds.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_core:item/baked_seeds" + } +} diff --git a/src/core/resources/assets/wild_wind_core/items/calamari.json b/src/core/resources/assets/wild_wind_core/items/calamari.json new file mode 100644 index 0000000..dd3b15e --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/items/calamari.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_core:item/calamari" + } +} diff --git a/src/core/resources/assets/wild_wind_core/items/cooked_calamari.json b/src/core/resources/assets/wild_wind_core/items/cooked_calamari.json new file mode 100644 index 0000000..1d94739 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/items/cooked_calamari.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_core:item/cooked_calamari" + } +} diff --git a/src/core/resources/assets/wild_wind_core/items/cooked_egg.json b/src/core/resources/assets/wild_wind_core/items/cooked_egg.json new file mode 100644 index 0000000..c092562 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/items/cooked_egg.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_core:item/cooked_egg" + } +} diff --git a/src/core/resources/assets/wild_wind_core/items/cooked_frog_legs.json b/src/core/resources/assets/wild_wind_core/items/cooked_frog_legs.json new file mode 100644 index 0000000..facfc88 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/items/cooked_frog_legs.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_core:item/cooked_frog_legs" + } +} diff --git a/src/core/resources/assets/wild_wind_core/items/duckweed.json b/src/core/resources/assets/wild_wind_core/items/duckweed.json new file mode 100644 index 0000000..1f73aa0 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/items/duckweed.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_core:item/duckweed" + } +} diff --git a/src/core/resources/assets/wild_wind_core/items/frog_legs.json b/src/core/resources/assets/wild_wind_core/items/frog_legs.json new file mode 100644 index 0000000..0794c66 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/items/frog_legs.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_core:item/frog_legs" + } +} diff --git a/src/core/resources/assets/wild_wind_core/items/kiln.json b/src/core/resources/assets/wild_wind_core/items/kiln.json new file mode 100644 index 0000000..0e832fb --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/items/kiln.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "minecraft:block/furnace" + } +} diff --git a/src/core/resources/assets/wild_wind_core/items/stripped_azalea_log.json b/src/core/resources/assets/wild_wind_core/items/stripped_azalea_log.json new file mode 100644 index 0000000..25189fd --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/items/stripped_azalea_log.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_core:block/stripped_azalea_log" + } +} diff --git a/src/core/resources/assets/wild_wind_core/items/stripped_azalea_wood.json b/src/core/resources/assets/wild_wind_core/items/stripped_azalea_wood.json new file mode 100644 index 0000000..2236039 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/items/stripped_azalea_wood.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_core:block/stripped_azalea_wood" + } +} diff --git a/src/core/resources/assets/wild_wind_core/lang/en_us.json b/src/core/resources/assets/wild_wind_core/lang/en_us.json new file mode 100644 index 0000000..7715a7d --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/lang/en_us.json @@ -0,0 +1,31 @@ +{ + "block.minecraft.oak_hanging_sign": "Azalea Wall Hanging Sign", + "block.minecraft.oak_sign": "Azalea Wall Sign", + "block.wild_wind_core.azalea_button": "Azalea Button", + "block.wild_wind_core.azalea_door": "Azalea Door", + "block.wild_wind_core.azalea_fence": "Azalea Fence", + "block.wild_wind_core.azalea_fence_gate": "Azalea Fence Gate", + "block.wild_wind_core.azalea_hanging_sign": "Azalea Hanging Sign", + "block.wild_wind_core.azalea_log": "Azalea Log", + "block.wild_wind_core.azalea_planks": "Azalea Planks", + "block.wild_wind_core.azalea_pressure_plate": "Azalea Pressure Plate", + "block.wild_wind_core.azalea_shelf": "Azalea Shelf", + "block.wild_wind_core.azalea_sign": "Azalea Sign", + "block.wild_wind_core.azalea_slab": "Azalea Slab", + "block.wild_wind_core.azalea_stairs": "Azalea Stairs", + "block.wild_wind_core.azalea_trapdoor": "Azalea Trapdoor", + "block.wild_wind_core.azalea_wood": "Azalea Wood", + "block.wild_wind_core.kiln": "Kiln", + "block.wild_wind_core.stripped_azalea_log": "Stripped Azalea Log", + "block.wild_wind_core.stripped_azalea_wood": "Stripped Azalea Wood", + "enchantment.wild_wind_core.melting": "Melting", + "item.wild_wind_core.baked_seeds": "Baked Seeds", + "item.wild_wind_core.calamari": "Calamari", + "item.wild_wind_core.cooked_calamari": "Cooked Calamari", + "item.wild_wind_core.cooked_egg": "Fried Egg", + "item.wild_wind_core.cooked_frog_legs": "Cooked Frog Legs", + "item.wild_wind_core.duckweed": "Duckweed", + "item.wild_wind_core.frog_legs": "Raw Frog Legs", + "mod.wild_wind.name": "Wild Wind", + "mod.wild_wind.core": "Wild Wind:Core" +} diff --git a/src/core/resources/assets/wild_wind_core/lang/zh_cn.json b/src/core/resources/assets/wild_wind_core/lang/zh_cn.json new file mode 100644 index 0000000..43671cd --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/lang/zh_cn.json @@ -0,0 +1,31 @@ +{ + "block.minecraft.oak_hanging_sign": "墙上的悬挂式杜鹃木告示牌", + "block.minecraft.oak_sign": "墙上的杜鹃木告示牌", + "block.wild_wind_core.azalea_button": "杜鹃木按钮", + "block.wild_wind_core.azalea_door": "杜鹃木门", + "block.wild_wind_core.azalea_fence": "杜鹃木栅栏", + "block.wild_wind_core.azalea_fence_gate": "杜鹃木栅栏门", + "block.wild_wind_core.azalea_hanging_sign": "悬挂式杜鹃木告示牌", + "block.wild_wind_core.azalea_log": "杜鹃木原木", + "block.wild_wind_core.azalea_planks": "杜鹃木木板", + "block.wild_wind_core.azalea_pressure_plate": "杜鹃木压力板", + "block.wild_wind_core.azalea_shelf": "杜鹃木展示架", + "block.wild_wind_core.azalea_sign": "杜鹃木告示牌", + "block.wild_wind_core.azalea_slab": "杜鹃木台阶", + "block.wild_wind_core.azalea_stairs": "杜鹃木楼梯", + "block.wild_wind_core.azalea_trapdoor": "杜鹃木活板门", + "block.wild_wind_core.azalea_wood": "杜鹃木", + "block.wild_wind_core.kiln": "窑炉", + "block.wild_wind_core.stripped_azalea_log": "去皮杜鹃木原木", + "block.wild_wind_core.stripped_azalea_wood": "去皮杜鹃木", + "enchantment.wild_wind_core.melting": "熔炼", + "item.wild_wind_core.baked_seeds": "烤种子", + "item.wild_wind_core.calamari": "鱿鱼须", + "item.wild_wind_core.cooked_calamari": "熟鱿鱼须", + "item.wild_wind_core.cooked_egg": "煎蛋", + "item.wild_wind_core.cooked_frog_legs": "熟蛙腿", + "item.wild_wind_core.duckweed": "浮萍", + "item.wild_wind_core.frog_legs": "生蛙腿", + "mod.wild_wind.name": "原野之风", + "mod.wild_wind.core": "原野之风:核心" +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_button.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_button.json new file mode 100644 index 0000000..f997e2a --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_button.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/button", + "textures": { + "texture": "wild_wind_core:block/azalea_planks" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_button_inventory.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_button_inventory.json new file mode 100644 index 0000000..d18c28d --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_button_inventory.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/button_inventory", + "textures": { + "texture": "wild_wind_core:block/azalea_planks" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_button_pressed.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_button_pressed.json new file mode 100644 index 0000000..7f213bb --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_button_pressed.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/button_pressed", + "textures": { + "texture": "wild_wind_core:block/azalea_planks" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_door_bottom_left.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_door_bottom_left.json new file mode 100644 index 0000000..2f1052e --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_door_bottom_left.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/door_bottom_left", + "textures": { + "bottom": "wild_wind_core:block/azalea_door_bottom", + "top": "wild_wind_core:block/azalea_door_top" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_door_bottom_left_open.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_door_bottom_left_open.json new file mode 100644 index 0000000..f093f9e --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_door_bottom_left_open.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/door_bottom_left_open", + "textures": { + "bottom": "wild_wind_core:block/azalea_door_bottom", + "top": "wild_wind_core:block/azalea_door_top" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_door_bottom_right.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_door_bottom_right.json new file mode 100644 index 0000000..2111cc8 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_door_bottom_right.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/door_bottom_right", + "textures": { + "bottom": "wild_wind_core:block/azalea_door_bottom", + "top": "wild_wind_core:block/azalea_door_top" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_door_bottom_right_open.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_door_bottom_right_open.json new file mode 100644 index 0000000..cf96a04 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_door_bottom_right_open.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/door_bottom_right_open", + "textures": { + "bottom": "wild_wind_core:block/azalea_door_bottom", + "top": "wild_wind_core:block/azalea_door_top" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_door_top_left.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_door_top_left.json new file mode 100644 index 0000000..eb067da --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_door_top_left.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/door_top_left", + "textures": { + "bottom": "wild_wind_core:block/azalea_door_bottom", + "top": "wild_wind_core:block/azalea_door_top" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_door_top_left_open.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_door_top_left_open.json new file mode 100644 index 0000000..dc23983 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_door_top_left_open.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/door_top_left_open", + "textures": { + "bottom": "wild_wind_core:block/azalea_door_bottom", + "top": "wild_wind_core:block/azalea_door_top" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_door_top_right.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_door_top_right.json new file mode 100644 index 0000000..87064cf --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_door_top_right.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/door_top_right", + "textures": { + "bottom": "wild_wind_core:block/azalea_door_bottom", + "top": "wild_wind_core:block/azalea_door_top" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_door_top_right_open.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_door_top_right_open.json new file mode 100644 index 0000000..f54028b --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_door_top_right_open.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/door_top_right_open", + "textures": { + "bottom": "wild_wind_core:block/azalea_door_bottom", + "top": "wild_wind_core:block/azalea_door_top" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_fence_gate.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_fence_gate.json new file mode 100644 index 0000000..8412e16 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_fence_gate.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/template_fence_gate", + "textures": { + "texture": "wild_wind_core:block/azalea_planks" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_fence_gate_open.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_fence_gate_open.json new file mode 100644 index 0000000..67d573e --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_fence_gate_open.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/template_fence_gate_open", + "textures": { + "texture": "wild_wind_core:block/azalea_planks" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_fence_gate_wall.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_fence_gate_wall.json new file mode 100644 index 0000000..c34ea72 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_fence_gate_wall.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/template_fence_gate_wall", + "textures": { + "texture": "wild_wind_core:block/azalea_planks" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_fence_gate_wall_open.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_fence_gate_wall_open.json new file mode 100644 index 0000000..5e353ff --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_fence_gate_wall_open.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/template_fence_gate_wall_open", + "textures": { + "texture": "wild_wind_core:block/azalea_planks" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_fence_inventory.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_fence_inventory.json new file mode 100644 index 0000000..fc7db85 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_fence_inventory.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/fence_inventory", + "textures": { + "texture": "wild_wind_core:block/azalea_planks" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_fence_post.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_fence_post.json new file mode 100644 index 0000000..80526bb --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_fence_post.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/fence_post", + "textures": { + "texture": "wild_wind_core:block/azalea_planks" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_fence_side.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_fence_side.json new file mode 100644 index 0000000..d7d2f71 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_fence_side.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/fence_side", + "textures": { + "texture": "wild_wind_core:block/azalea_planks" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_hanging_sign_attached_rot_0.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_hanging_sign_attached_rot_0.json new file mode 100644 index 0000000..bd50e99 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_hanging_sign_attached_rot_0.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_attached_hanging_sign_rot_0", + "textures": { + "all": "wild_wind_core:block/azalea_hanging_sign", + "particle": "wild_wind_core:block/stripped_azalea_log" + } +} \ No newline at end of file diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_hanging_sign_attached_rot_1.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_hanging_sign_attached_rot_1.json new file mode 100644 index 0000000..defad0f --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_hanging_sign_attached_rot_1.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_attached_hanging_sign_rot_1", + "textures": { + "all": "wild_wind_core:block/azalea_hanging_sign", + "particle": "wild_wind_core:block/stripped_azalea_log" + } +} \ No newline at end of file diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_hanging_sign_attached_rot_2.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_hanging_sign_attached_rot_2.json new file mode 100644 index 0000000..68faae4 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_hanging_sign_attached_rot_2.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_attached_hanging_sign_rot_2", + "textures": { + "all": "wild_wind_core:block/azalea_hanging_sign", + "particle": "wild_wind_core:block/stripped_azalea_log" + } +} \ No newline at end of file diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_hanging_sign_attached_rot_3.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_hanging_sign_attached_rot_3.json new file mode 100644 index 0000000..96ddfef --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_hanging_sign_attached_rot_3.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_attached_hanging_sign_rot_3", + "textures": { + "all": "wild_wind_core:block/azalea_hanging_sign", + "particle": "wild_wind_core:block/stripped_azalea_log" + } +} \ No newline at end of file diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_hanging_sign_rot_0.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_hanging_sign_rot_0.json new file mode 100644 index 0000000..57441d8 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_hanging_sign_rot_0.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_hanging_sign_rot_0", + "textures": { + "all": "wild_wind_core:block/azalea_hanging_sign", + "particle": "wild_wind_core:block/stripped_azalea_log" + } +} \ No newline at end of file diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_hanging_sign_rot_1.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_hanging_sign_rot_1.json new file mode 100644 index 0000000..ceb03ee --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_hanging_sign_rot_1.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_hanging_sign_rot_1", + "textures": { + "all": "wild_wind_core:block/azalea_hanging_sign", + "particle": "wild_wind_core:block/stripped_azalea_log" + } +} \ No newline at end of file diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_hanging_sign_rot_2.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_hanging_sign_rot_2.json new file mode 100644 index 0000000..439fec8 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_hanging_sign_rot_2.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_hanging_sign_rot_2", + "textures": { + "all": "wild_wind_core:block/azalea_hanging_sign", + "particle": "wild_wind_core:block/stripped_azalea_log" + } +} \ No newline at end of file diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_hanging_sign_rot_3.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_hanging_sign_rot_3.json new file mode 100644 index 0000000..4053d81 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_hanging_sign_rot_3.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_hanging_sign_rot_3", + "textures": { + "all": "wild_wind_core:block/azalea_hanging_sign", + "particle": "wild_wind_core:block/stripped_azalea_log" + } +} \ No newline at end of file diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_log.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_log.json new file mode 100644 index 0000000..da4f5ff --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_log.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/cube_column", + "textures": { + "end": "wild_wind_core:block/azalea_log_top", + "side": "wild_wind_core:block/azalea_log" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_log_horizontal.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_log_horizontal.json new file mode 100644 index 0000000..64c5bc0 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_log_horizontal.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/cube_column_horizontal", + "textures": { + "end": "wild_wind_core:block/azalea_log_top", + "side": "wild_wind_core:block/azalea_log" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_planks.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_planks.json new file mode 100644 index 0000000..a98b278 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_planks.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cube_all", + "textures": { + "all": "wild_wind_core:block/azalea_planks" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_pressure_plate.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_pressure_plate.json new file mode 100644 index 0000000..37648c4 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_pressure_plate.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/pressure_plate_up", + "textures": { + "texture": "wild_wind_core:block/azalea_planks" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_pressure_plate_down.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_pressure_plate_down.json new file mode 100644 index 0000000..b0a2470 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_pressure_plate_down.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/pressure_plate_down", + "textures": { + "texture": "wild_wind_core:block/azalea_planks" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_shelf.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_shelf.json new file mode 100644 index 0000000..de4caf8 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_shelf.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_shelf_body", + "textures": { + "all": "wild_wind_core:block/azalea_shelf", + "particle": "wild_wind_core:block/stripped_azalea_log" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_shelf_center.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_shelf_center.json new file mode 100644 index 0000000..6c25513 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_shelf_center.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_shelf_center", + "textures": { + "all": "wild_wind_core:block/azalea_shelf", + "particle": "wild_wind_core:block/stripped_azalea_log" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_shelf_inventory.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_shelf_inventory.json new file mode 100644 index 0000000..cdef7ed --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_shelf_inventory.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_shelf_inventory", + "textures": { + "all": "wild_wind_core:block/azalea_shelf", + "particle": "wild_wind_core:block/stripped_azalea_log" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_shelf_left.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_shelf_left.json new file mode 100644 index 0000000..efd9d35 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_shelf_left.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_shelf_left", + "textures": { + "all": "wild_wind_core:block/azalea_shelf", + "particle": "wild_wind_core:block/stripped_azalea_log" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_shelf_right.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_shelf_right.json new file mode 100644 index 0000000..4e24539 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_shelf_right.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_shelf_right", + "textures": { + "all": "wild_wind_core:block/azalea_shelf", + "particle": "wild_wind_core:block/stripped_azalea_log" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_shelf_unconnected.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_shelf_unconnected.json new file mode 100644 index 0000000..48cec4c --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_shelf_unconnected.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_shelf_unconnected", + "textures": { + "all": "wild_wind_core:block/azalea_shelf", + "particle": "wild_wind_core:block/stripped_azalea_log" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_shelf_unpowered.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_shelf_unpowered.json new file mode 100644 index 0000000..8dc9612 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_shelf_unpowered.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_shelf_unpowered", + "textures": { + "all": "wild_wind_core:block/azalea_shelf", + "particle": "wild_wind_core:block/stripped_azalea_log" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_sign_rot_0.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_sign_rot_0.json new file mode 100644 index 0000000..cd0f20f --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_sign_rot_0.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_sign_rot_0", + "textures": { + "all": "wild_wind_core:block/azalea_sign", + "particle": "wild_wind_core:block/azalea_planks" + } +} \ No newline at end of file diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_sign_rot_1.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_sign_rot_1.json new file mode 100644 index 0000000..d9662fa --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_sign_rot_1.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_sign_rot_1", + "textures": { + "all": "wild_wind_core:block/azalea_sign", + "particle": "wild_wind_core:block/azalea_planks" + } +} \ No newline at end of file diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_sign_rot_2.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_sign_rot_2.json new file mode 100644 index 0000000..1405e83 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_sign_rot_2.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_sign_rot_2", + "textures": { + "all": "wild_wind_core:block/azalea_sign", + "particle": "wild_wind_core:block/azalea_planks" + } +} \ No newline at end of file diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_sign_rot_3.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_sign_rot_3.json new file mode 100644 index 0000000..a469dd6 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_sign_rot_3.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_sign_rot_3", + "textures": { + "all": "wild_wind_core:block/azalea_sign", + "particle": "wild_wind_core:block/azalea_planks" + } +} \ No newline at end of file diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_slab.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_slab.json new file mode 100644 index 0000000..7e09f48 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_slab.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/slab", + "textures": { + "bottom": "wild_wind_core:block/azalea_planks", + "side": "wild_wind_core:block/azalea_planks", + "top": "wild_wind_core:block/azalea_planks" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_slab_top.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_slab_top.json new file mode 100644 index 0000000..ba35d83 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_slab_top.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/slab_top", + "textures": { + "bottom": "wild_wind_core:block/azalea_planks", + "side": "wild_wind_core:block/azalea_planks", + "top": "wild_wind_core:block/azalea_planks" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_stairs.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_stairs.json new file mode 100644 index 0000000..e3e7594 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_stairs.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/stairs", + "textures": { + "bottom": "wild_wind_core:block/azalea_planks", + "side": "wild_wind_core:block/azalea_planks", + "top": "wild_wind_core:block/azalea_planks" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_stairs_inner.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_stairs_inner.json new file mode 100644 index 0000000..bed78d8 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_stairs_inner.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/inner_stairs", + "textures": { + "bottom": "wild_wind_core:block/azalea_planks", + "side": "wild_wind_core:block/azalea_planks", + "top": "wild_wind_core:block/azalea_planks" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_stairs_outer.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_stairs_outer.json new file mode 100644 index 0000000..a3ffb2c --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_stairs_outer.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/outer_stairs", + "textures": { + "bottom": "wild_wind_core:block/azalea_planks", + "side": "wild_wind_core:block/azalea_planks", + "top": "wild_wind_core:block/azalea_planks" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_trapdoor_bottom.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_trapdoor_bottom.json new file mode 100644 index 0000000..b521700 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_trapdoor_bottom.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/template_trapdoor_bottom", + "textures": { + "texture": "wild_wind_core:block/azalea_trapdoor" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_trapdoor_open.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_trapdoor_open.json new file mode 100644 index 0000000..9da8355 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_trapdoor_open.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/template_trapdoor_open", + "textures": { + "texture": "wild_wind_core:block/azalea_trapdoor" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_trapdoor_top.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_trapdoor_top.json new file mode 100644 index 0000000..06065f3 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_trapdoor_top.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/template_trapdoor_top", + "textures": { + "texture": "wild_wind_core:block/azalea_trapdoor" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_wall_hanging_sign.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_wall_hanging_sign.json new file mode 100644 index 0000000..5a663e0 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_wall_hanging_sign.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_wall_hanging_sign", + "textures": { + "all": "wild_wind_core:block/azalea_hanging_sign", + "particle": "wild_wind_core:block/stripped_azalea_log" + } +} \ No newline at end of file diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_wall_sign.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_wall_sign.json new file mode 100644 index 0000000..39d0827 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_wall_sign.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_wall_sign", + "textures": { + "all": "wild_wind_core:block/azalea_sign", + "particle": "wild_wind_core:block/azalea_planks" + } +} \ No newline at end of file diff --git a/src/core/resources/assets/wild_wind_core/models/block/azalea_wood.json b/src/core/resources/assets/wild_wind_core/models/block/azalea_wood.json new file mode 100644 index 0000000..671ae85 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/azalea_wood.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/cube_column", + "textures": { + "end": "wild_wind_core:block/azalea_log", + "side": "wild_wind_core:block/azalea_log" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/stripped_azalea_log.json b/src/core/resources/assets/wild_wind_core/models/block/stripped_azalea_log.json new file mode 100644 index 0000000..f58edb9 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/stripped_azalea_log.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/cube_column", + "textures": { + "end": "wild_wind_core:block/stripped_azalea_log_top", + "side": "wild_wind_core:block/stripped_azalea_log" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/stripped_azalea_log_horizontal.json b/src/core/resources/assets/wild_wind_core/models/block/stripped_azalea_log_horizontal.json new file mode 100644 index 0000000..47fb80a --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/stripped_azalea_log_horizontal.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/cube_column_horizontal", + "textures": { + "end": "wild_wind_core:block/stripped_azalea_log_top", + "side": "wild_wind_core:block/stripped_azalea_log" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/block/stripped_azalea_wood.json b/src/core/resources/assets/wild_wind_core/models/block/stripped_azalea_wood.json new file mode 100644 index 0000000..e853fe1 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/block/stripped_azalea_wood.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/cube_column", + "textures": { + "end": "wild_wind_core:block/stripped_azalea_log", + "side": "wild_wind_core:block/stripped_azalea_log" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/item/azalea_boat.json b/src/core/resources/assets/wild_wind_core/models/item/azalea_boat.json new file mode 100644 index 0000000..32c784e --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/item/azalea_boat.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wild_wind_core:item/azalea_boat" + } +} \ No newline at end of file diff --git a/src/core/resources/assets/wild_wind_core/models/item/azalea_chest_boat.json b/src/core/resources/assets/wild_wind_core/models/item/azalea_chest_boat.json new file mode 100644 index 0000000..ef113c3 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/item/azalea_chest_boat.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wild_wind_core:item/azalea_chest_boat" + } +} \ No newline at end of file diff --git a/src/core/resources/assets/wild_wind_core/models/item/azalea_door.json b/src/core/resources/assets/wild_wind_core/models/item/azalea_door.json new file mode 100644 index 0000000..49c9a93 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/item/azalea_door.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wild_wind_core:item/azalea_door" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/item/azalea_hanging_sign.json b/src/core/resources/assets/wild_wind_core/models/item/azalea_hanging_sign.json new file mode 100644 index 0000000..946de22 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/item/azalea_hanging_sign.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wild_wind_core:item/azalea_hanging_sign" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/item/azalea_sign.json b/src/core/resources/assets/wild_wind_core/models/item/azalea_sign.json new file mode 100644 index 0000000..e2765b9 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/item/azalea_sign.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wild_wind_core:item/azalea_sign" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/item/baked_seeds.json b/src/core/resources/assets/wild_wind_core/models/item/baked_seeds.json new file mode 100644 index 0000000..56944af --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/item/baked_seeds.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wild_wind_core:item/baked_seeds" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/item/calamari.json b/src/core/resources/assets/wild_wind_core/models/item/calamari.json new file mode 100644 index 0000000..1bda34a --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/item/calamari.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wild_wind_core:item/calamari" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/item/cooked_calamari.json b/src/core/resources/assets/wild_wind_core/models/item/cooked_calamari.json new file mode 100644 index 0000000..30b5120 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/item/cooked_calamari.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wild_wind_core:item/cooked_calamari" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/item/cooked_egg.json b/src/core/resources/assets/wild_wind_core/models/item/cooked_egg.json new file mode 100644 index 0000000..f70f905 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/item/cooked_egg.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wild_wind_core:item/cooked_egg" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/item/cooked_frog_legs.json b/src/core/resources/assets/wild_wind_core/models/item/cooked_frog_legs.json new file mode 100644 index 0000000..fe636a0 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/item/cooked_frog_legs.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wild_wind_core:item/cooked_frog_legs" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/item/duckweed.json b/src/core/resources/assets/wild_wind_core/models/item/duckweed.json new file mode 100644 index 0000000..579676d --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/item/duckweed.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wild_wind_core:item/duckweed" + } +} diff --git a/src/core/resources/assets/wild_wind_core/models/item/frog_legs.json b/src/core/resources/assets/wild_wind_core/models/item/frog_legs.json new file mode 100644 index 0000000..f64eaf7 --- /dev/null +++ b/src/core/resources/assets/wild_wind_core/models/item/frog_legs.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wild_wind_core:item/frog_legs" + } +} diff --git a/src/hfas/resources/assets/ww_hfas/textures/block/azalea_door_bottom.png b/src/core/resources/assets/wild_wind_core/textures/block/azalea_door_bottom.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/block/azalea_door_bottom.png rename to src/core/resources/assets/wild_wind_core/textures/block/azalea_door_bottom.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/block/azalea_door_top.png b/src/core/resources/assets/wild_wind_core/textures/block/azalea_door_top.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/block/azalea_door_top.png rename to src/core/resources/assets/wild_wind_core/textures/block/azalea_door_top.png diff --git a/src/core/resources/assets/wild_wind_core/textures/block/azalea_hanging_sign.png b/src/core/resources/assets/wild_wind_core/textures/block/azalea_hanging_sign.png new file mode 100644 index 0000000..fe7e2a0 Binary files /dev/null and b/src/core/resources/assets/wild_wind_core/textures/block/azalea_hanging_sign.png differ diff --git a/src/hfas/resources/assets/ww_hfas/textures/block/azalea_log.png b/src/core/resources/assets/wild_wind_core/textures/block/azalea_log.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/block/azalea_log.png rename to src/core/resources/assets/wild_wind_core/textures/block/azalea_log.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/block/azalea_log_top.png b/src/core/resources/assets/wild_wind_core/textures/block/azalea_log_top.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/block/azalea_log_top.png rename to src/core/resources/assets/wild_wind_core/textures/block/azalea_log_top.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/block/azalea_planks.png b/src/core/resources/assets/wild_wind_core/textures/block/azalea_planks.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/block/azalea_planks.png rename to src/core/resources/assets/wild_wind_core/textures/block/azalea_planks.png diff --git a/src/core/resources/assets/wild_wind_core/textures/block/azalea_shelf.png b/src/core/resources/assets/wild_wind_core/textures/block/azalea_shelf.png new file mode 100644 index 0000000..f92da58 Binary files /dev/null and b/src/core/resources/assets/wild_wind_core/textures/block/azalea_shelf.png differ diff --git a/src/core/resources/assets/wild_wind_core/textures/block/azalea_sign.png b/src/core/resources/assets/wild_wind_core/textures/block/azalea_sign.png new file mode 100644 index 0000000..3252f87 Binary files /dev/null and b/src/core/resources/assets/wild_wind_core/textures/block/azalea_sign.png differ diff --git a/src/hfas/resources/assets/ww_hfas/textures/block/azalea_trapdoor.png b/src/core/resources/assets/wild_wind_core/textures/block/azalea_trapdoor.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/block/azalea_trapdoor.png rename to src/core/resources/assets/wild_wind_core/textures/block/azalea_trapdoor.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/block/stripped_azalea_log.png b/src/core/resources/assets/wild_wind_core/textures/block/stripped_azalea_log.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/block/stripped_azalea_log.png rename to src/core/resources/assets/wild_wind_core/textures/block/stripped_azalea_log.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/block/stripped_azalea_log_top.png b/src/core/resources/assets/wild_wind_core/textures/block/stripped_azalea_log_top.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/block/stripped_azalea_log_top.png rename to src/core/resources/assets/wild_wind_core/textures/block/stripped_azalea_log_top.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/entity/boat/azalea.png b/src/core/resources/assets/wild_wind_core/textures/entity/boat/azalea.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/entity/boat/azalea.png rename to src/core/resources/assets/wild_wind_core/textures/entity/boat/azalea.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/entity/chest_boat/azalea.png b/src/core/resources/assets/wild_wind_core/textures/entity/chest_boat/azalea.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/entity/chest_boat/azalea.png rename to src/core/resources/assets/wild_wind_core/textures/entity/chest_boat/azalea.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/entity/signs/azalea.png b/src/core/resources/assets/wild_wind_core/textures/entity/signs/azalea.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/entity/signs/azalea.png rename to src/core/resources/assets/wild_wind_core/textures/entity/signs/azalea.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/entity/signs/hanging/azalea.png b/src/core/resources/assets/wild_wind_core/textures/entity/signs/hanging/azalea.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/entity/signs/hanging/azalea.png rename to src/core/resources/assets/wild_wind_core/textures/entity/signs/hanging/azalea.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/gui/hanging_signs/azalea.png b/src/core/resources/assets/wild_wind_core/textures/gui/hanging_signs/azalea.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/gui/hanging_signs/azalea.png rename to src/core/resources/assets/wild_wind_core/textures/gui/hanging_signs/azalea.png diff --git a/src/core/resources/assets/wild_wind_core/textures/gui/signs/azalea.png b/src/core/resources/assets/wild_wind_core/textures/gui/signs/azalea.png new file mode 100644 index 0000000..3880172 Binary files /dev/null and b/src/core/resources/assets/wild_wind_core/textures/gui/signs/azalea.png differ diff --git a/src/hfas/resources/assets/ww_hfas/textures/item/azalea_boat.png b/src/core/resources/assets/wild_wind_core/textures/item/azalea_boat.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/item/azalea_boat.png rename to src/core/resources/assets/wild_wind_core/textures/item/azalea_boat.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/item/azalea_chest_boat.png b/src/core/resources/assets/wild_wind_core/textures/item/azalea_chest_boat.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/item/azalea_chest_boat.png rename to src/core/resources/assets/wild_wind_core/textures/item/azalea_chest_boat.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/item/azalea_door.png b/src/core/resources/assets/wild_wind_core/textures/item/azalea_door.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/item/azalea_door.png rename to src/core/resources/assets/wild_wind_core/textures/item/azalea_door.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/item/azalea_hanging_sign.png b/src/core/resources/assets/wild_wind_core/textures/item/azalea_hanging_sign.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/item/azalea_hanging_sign.png rename to src/core/resources/assets/wild_wind_core/textures/item/azalea_hanging_sign.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/item/azalea_sign.png b/src/core/resources/assets/wild_wind_core/textures/item/azalea_sign.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/item/azalea_sign.png rename to src/core/resources/assets/wild_wind_core/textures/item/azalea_sign.png diff --git a/src/core/resources/assets/wild_wind_core/textures/item/baked_seeds.png b/src/core/resources/assets/wild_wind_core/textures/item/baked_seeds.png new file mode 100644 index 0000000..78e4bcc Binary files /dev/null and b/src/core/resources/assets/wild_wind_core/textures/item/baked_seeds.png differ diff --git a/src/core/resources/assets/wild_wind_core/textures/item/calamari.png b/src/core/resources/assets/wild_wind_core/textures/item/calamari.png new file mode 100644 index 0000000..963ea16 Binary files /dev/null and b/src/core/resources/assets/wild_wind_core/textures/item/calamari.png differ diff --git a/src/core/resources/assets/wild_wind_core/textures/item/cooked_calamari.png b/src/core/resources/assets/wild_wind_core/textures/item/cooked_calamari.png new file mode 100644 index 0000000..28d0809 Binary files /dev/null and b/src/core/resources/assets/wild_wind_core/textures/item/cooked_calamari.png differ diff --git a/src/core/resources/assets/wild_wind_core/textures/item/cooked_egg.png b/src/core/resources/assets/wild_wind_core/textures/item/cooked_egg.png new file mode 100644 index 0000000..8ea9d32 Binary files /dev/null and b/src/core/resources/assets/wild_wind_core/textures/item/cooked_egg.png differ diff --git a/src/core/resources/assets/wild_wind_core/textures/item/cooked_frog_legs.png b/src/core/resources/assets/wild_wind_core/textures/item/cooked_frog_legs.png new file mode 100644 index 0000000..bd064fa Binary files /dev/null and b/src/core/resources/assets/wild_wind_core/textures/item/cooked_frog_legs.png differ diff --git a/src/core/resources/assets/wild_wind_core/textures/item/duckweed.png b/src/core/resources/assets/wild_wind_core/textures/item/duckweed.png new file mode 100644 index 0000000..2bafc6d Binary files /dev/null and b/src/core/resources/assets/wild_wind_core/textures/item/duckweed.png differ diff --git a/src/core/resources/assets/wild_wind_core/textures/item/frog_legs.png b/src/core/resources/assets/wild_wind_core/textures/item/frog_legs.png new file mode 100644 index 0000000..90d6aef Binary files /dev/null and b/src/core/resources/assets/wild_wind_core/textures/item/frog_legs.png differ diff --git a/src/core/resources/data/c/tags/block/fence_gates/wooden.json b/src/core/resources/data/c/tags/block/fence_gates/wooden.json new file mode 100644 index 0000000..5cecd6d --- /dev/null +++ b/src/core/resources/data/c/tags/block/fence_gates/wooden.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:azalea_fence_gate" + ] +} diff --git a/src/core/resources/data/c/tags/block/fences.json b/src/core/resources/data/c/tags/block/fences.json new file mode 100644 index 0000000..6115af8 --- /dev/null +++ b/src/core/resources/data/c/tags/block/fences.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:azalea_fence" + ] +} diff --git a/src/core/resources/data/c/tags/block/fences/wooden.json b/src/core/resources/data/c/tags/block/fences/wooden.json new file mode 100644 index 0000000..6115af8 --- /dev/null +++ b/src/core/resources/data/c/tags/block/fences/wooden.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:azalea_fence" + ] +} diff --git a/src/core/resources/data/c/tags/block/stripped_logs.json b/src/core/resources/data/c/tags/block/stripped_logs.json new file mode 100644 index 0000000..107a4aa --- /dev/null +++ b/src/core/resources/data/c/tags/block/stripped_logs.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:stripped_azalea_log" + ] +} diff --git a/src/core/resources/data/c/tags/block/stripped_woods.json b/src/core/resources/data/c/tags/block/stripped_woods.json new file mode 100644 index 0000000..cafecb7 --- /dev/null +++ b/src/core/resources/data/c/tags/block/stripped_woods.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:stripped_azalea_wood" + ] +} diff --git a/src/core/resources/data/c/tags/item/fence_gates/wooden.json b/src/core/resources/data/c/tags/item/fence_gates/wooden.json new file mode 100644 index 0000000..5cecd6d --- /dev/null +++ b/src/core/resources/data/c/tags/item/fence_gates/wooden.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:azalea_fence_gate" + ] +} diff --git a/src/core/resources/data/c/tags/item/fences/wooden.json b/src/core/resources/data/c/tags/item/fences/wooden.json new file mode 100644 index 0000000..6115af8 --- /dev/null +++ b/src/core/resources/data/c/tags/item/fences/wooden.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:azalea_fence" + ] +} diff --git a/src/core/resources/data/c/tags/item/stripped_logs.json b/src/core/resources/data/c/tags/item/stripped_logs.json new file mode 100644 index 0000000..107a4aa --- /dev/null +++ b/src/core/resources/data/c/tags/item/stripped_logs.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:stripped_azalea_log" + ] +} diff --git a/src/core/resources/data/c/tags/item/stripped_woods.json b/src/core/resources/data/c/tags/item/stripped_woods.json new file mode 100644 index 0000000..cafecb7 --- /dev/null +++ b/src/core/resources/data/c/tags/item/stripped_woods.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:stripped_azalea_wood" + ] +} diff --git a/src/core/resources/data/minecraft/tags/block/all_hanging_signs.json b/src/core/resources/data/minecraft/tags/block/all_hanging_signs.json new file mode 100644 index 0000000..102b637 --- /dev/null +++ b/src/core/resources/data/minecraft/tags/block/all_hanging_signs.json @@ -0,0 +1,12 @@ +{ + "values": [ + { + "required": false, + "id": "wild_wind_core:azalea_hanging_sign" + }, + { + "required": false, + "id": "wild_wind_core:azalea_wall_hanging_sign" + } + ] +} diff --git a/src/core/resources/data/minecraft/tags/block/all_signs.json b/src/core/resources/data/minecraft/tags/block/all_signs.json new file mode 100644 index 0000000..802bbd4 --- /dev/null +++ b/src/core/resources/data/minecraft/tags/block/all_signs.json @@ -0,0 +1,12 @@ +{ + "values": [ + { + "required": false, + "id": "wild_wind_core:azalea_sign" + }, + { + "required": false, + "id": "wild_wind_core:azalea_wall_sign" + } + ] +} diff --git a/src/core/resources/data/minecraft/tags/block/ceiling_hanging_signs.json b/src/core/resources/data/minecraft/tags/block/ceiling_hanging_signs.json new file mode 100644 index 0000000..b114ed6 --- /dev/null +++ b/src/core/resources/data/minecraft/tags/block/ceiling_hanging_signs.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:azalea_hanging_sign" + ] +} diff --git a/src/core/resources/data/minecraft/tags/block/doors.json b/src/core/resources/data/minecraft/tags/block/doors.json new file mode 100644 index 0000000..ec33762 --- /dev/null +++ b/src/core/resources/data/minecraft/tags/block/doors.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:azalea_door" + ] +} diff --git a/src/core/resources/data/minecraft/tags/block/fence_gates.json b/src/core/resources/data/minecraft/tags/block/fence_gates.json new file mode 100644 index 0000000..5cecd6d --- /dev/null +++ b/src/core/resources/data/minecraft/tags/block/fence_gates.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:azalea_fence_gate" + ] +} diff --git a/src/core/resources/data/minecraft/tags/block/fences.json b/src/core/resources/data/minecraft/tags/block/fences.json new file mode 100644 index 0000000..6115af8 --- /dev/null +++ b/src/core/resources/data/minecraft/tags/block/fences.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:azalea_fence" + ] +} diff --git a/src/core/resources/data/minecraft/tags/block/logs.json b/src/core/resources/data/minecraft/tags/block/logs.json new file mode 100644 index 0000000..8d968e5 --- /dev/null +++ b/src/core/resources/data/minecraft/tags/block/logs.json @@ -0,0 +1,8 @@ +{ + "values": [ + "wild_wind_core:azalea_log", + "wild_wind_core:azalea_wood", + "wild_wind_core:stripped_azalea_log", + "wild_wind_core:stripped_azalea_wood" + ] +} diff --git a/src/core/resources/data/minecraft/tags/block/logs_that_burn.json b/src/core/resources/data/minecraft/tags/block/logs_that_burn.json new file mode 100644 index 0000000..8d968e5 --- /dev/null +++ b/src/core/resources/data/minecraft/tags/block/logs_that_burn.json @@ -0,0 +1,8 @@ +{ + "values": [ + "wild_wind_core:azalea_log", + "wild_wind_core:azalea_wood", + "wild_wind_core:stripped_azalea_log", + "wild_wind_core:stripped_azalea_wood" + ] +} diff --git a/src/core/resources/data/minecraft/tags/block/mineable/axe.json b/src/core/resources/data/minecraft/tags/block/mineable/axe.json new file mode 100644 index 0000000..3a14d79 --- /dev/null +++ b/src/core/resources/data/minecraft/tags/block/mineable/axe.json @@ -0,0 +1,22 @@ +{ + "values": [ + "wild_wind_core:azalea_sign", + "wild_wind_core:azalea_wall_sign", + "wild_wind_core:azalea_hanging_sign", + "wild_wind_core:azalea_wall_hanging_sign", + "wild_wind_core:azalea_shelf", + "wild_wind_core:azalea_log", + "wild_wind_core:azalea_wood", + "wild_wind_core:stripped_azalea_log", + "wild_wind_core:stripped_azalea_wood", + "wild_wind_core:azalea_planks", + "wild_wind_core:azalea_stairs", + "wild_wind_core:azalea_slab", + "wild_wind_core:azalea_fence", + "wild_wind_core:azalea_fence_gate", + "wild_wind_core:azalea_door", + "wild_wind_core:azalea_trapdoor", + "wild_wind_core:azalea_pressure_plate", + "wild_wind_core:azalea_button" + ] +} diff --git a/src/core/resources/data/minecraft/tags/block/mineable/pickaxe.json b/src/core/resources/data/minecraft/tags/block/mineable/pickaxe.json new file mode 100644 index 0000000..fdcdae0 --- /dev/null +++ b/src/core/resources/data/minecraft/tags/block/mineable/pickaxe.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:kiln" + ] +} diff --git a/src/core/resources/data/minecraft/tags/block/needs_stone_tool.json b/src/core/resources/data/minecraft/tags/block/needs_stone_tool.json new file mode 100644 index 0000000..490112d --- /dev/null +++ b/src/core/resources/data/minecraft/tags/block/needs_stone_tool.json @@ -0,0 +1,17 @@ +{ + "values": [ + "wild_wind_core:azalea_log", + "wild_wind_core:azalea_wood", + "wild_wind_core:stripped_azalea_log", + "wild_wind_core:stripped_azalea_wood", + "wild_wind_core:azalea_planks", + "wild_wind_core:azalea_stairs", + "wild_wind_core:azalea_slab", + "wild_wind_core:azalea_fence", + "wild_wind_core:azalea_fence_gate", + "wild_wind_core:azalea_door", + "wild_wind_core:azalea_trapdoor", + "wild_wind_core:azalea_pressure_plate", + "wild_wind_core:azalea_button" + ] +} diff --git a/src/core/resources/data/minecraft/tags/block/overworld_natural_logs.json b/src/core/resources/data/minecraft/tags/block/overworld_natural_logs.json new file mode 100644 index 0000000..c73ac3a --- /dev/null +++ b/src/core/resources/data/minecraft/tags/block/overworld_natural_logs.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:azalea_log" + ] +} diff --git a/src/core/resources/data/minecraft/tags/block/planks.json b/src/core/resources/data/minecraft/tags/block/planks.json new file mode 100644 index 0000000..3a64f8f --- /dev/null +++ b/src/core/resources/data/minecraft/tags/block/planks.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:azalea_planks" + ] +} diff --git a/src/core/resources/data/minecraft/tags/block/standing_signs.json b/src/core/resources/data/minecraft/tags/block/standing_signs.json new file mode 100644 index 0000000..3d85148 --- /dev/null +++ b/src/core/resources/data/minecraft/tags/block/standing_signs.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:azalea_sign" + ] +} diff --git a/src/core/resources/data/minecraft/tags/block/trapdoors.json b/src/core/resources/data/minecraft/tags/block/trapdoors.json new file mode 100644 index 0000000..3758f81 --- /dev/null +++ b/src/core/resources/data/minecraft/tags/block/trapdoors.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:azalea_trapdoor" + ] +} diff --git a/src/core/resources/data/minecraft/tags/block/wall_hanging_signs.json b/src/core/resources/data/minecraft/tags/block/wall_hanging_signs.json new file mode 100644 index 0000000..927dd44 --- /dev/null +++ b/src/core/resources/data/minecraft/tags/block/wall_hanging_signs.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:azalea_wall_hanging_sign" + ] +} diff --git a/src/core/resources/data/minecraft/tags/block/wall_signs.json b/src/core/resources/data/minecraft/tags/block/wall_signs.json new file mode 100644 index 0000000..3a80830 --- /dev/null +++ b/src/core/resources/data/minecraft/tags/block/wall_signs.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:azalea_wall_sign" + ] +} diff --git a/src/core/resources/data/minecraft/tags/block/wooden_buttons.json b/src/core/resources/data/minecraft/tags/block/wooden_buttons.json new file mode 100644 index 0000000..e116c67 --- /dev/null +++ b/src/core/resources/data/minecraft/tags/block/wooden_buttons.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:azalea_button" + ] +} diff --git a/src/core/resources/data/minecraft/tags/block/wooden_doors.json b/src/core/resources/data/minecraft/tags/block/wooden_doors.json new file mode 100644 index 0000000..ec33762 --- /dev/null +++ b/src/core/resources/data/minecraft/tags/block/wooden_doors.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:azalea_door" + ] +} diff --git a/src/core/resources/data/minecraft/tags/block/wooden_fences.json b/src/core/resources/data/minecraft/tags/block/wooden_fences.json new file mode 100644 index 0000000..6115af8 --- /dev/null +++ b/src/core/resources/data/minecraft/tags/block/wooden_fences.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:azalea_fence" + ] +} diff --git a/src/core/resources/data/minecraft/tags/block/wooden_pressure_plates.json b/src/core/resources/data/minecraft/tags/block/wooden_pressure_plates.json new file mode 100644 index 0000000..4cae1b8 --- /dev/null +++ b/src/core/resources/data/minecraft/tags/block/wooden_pressure_plates.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:azalea_pressure_plate" + ] +} diff --git a/src/core/resources/data/minecraft/tags/block/wooden_shelves.json b/src/core/resources/data/minecraft/tags/block/wooden_shelves.json new file mode 100644 index 0000000..83fd298 --- /dev/null +++ b/src/core/resources/data/minecraft/tags/block/wooden_shelves.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:azalea_shelf" + ] +} diff --git a/src/core/resources/data/minecraft/tags/block/wooden_slabs.json b/src/core/resources/data/minecraft/tags/block/wooden_slabs.json new file mode 100644 index 0000000..a1c4e5b --- /dev/null +++ b/src/core/resources/data/minecraft/tags/block/wooden_slabs.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:azalea_slab" + ] +} diff --git a/src/core/resources/data/minecraft/tags/block/wooden_stairs.json b/src/core/resources/data/minecraft/tags/block/wooden_stairs.json new file mode 100644 index 0000000..193f12f --- /dev/null +++ b/src/core/resources/data/minecraft/tags/block/wooden_stairs.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:azalea_stairs" + ] +} diff --git a/src/core/resources/data/minecraft/tags/block/wooden_trapdoors.json b/src/core/resources/data/minecraft/tags/block/wooden_trapdoors.json new file mode 100644 index 0000000..3758f81 --- /dev/null +++ b/src/core/resources/data/minecraft/tags/block/wooden_trapdoors.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:azalea_trapdoor" + ] +} diff --git a/src/core/resources/data/minecraft/tags/enchantment/in_enchanting_table.json b/src/core/resources/data/minecraft/tags/enchantment/in_enchanting_table.json new file mode 100644 index 0000000..0dc395d --- /dev/null +++ b/src/core/resources/data/minecraft/tags/enchantment/in_enchanting_table.json @@ -0,0 +1,4 @@ +{ + "replace": false, + "values": ["wild_wind_core:melting"] +} diff --git a/src/core/resources/data/minecraft/tags/enchantment/non_treasure.json b/src/core/resources/data/minecraft/tags/enchantment/non_treasure.json new file mode 100644 index 0000000..f02fbef --- /dev/null +++ b/src/core/resources/data/minecraft/tags/enchantment/non_treasure.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "wild_wind_core:melting" + ] +} diff --git a/src/core/resources/data/minecraft/tags/item/boats.json b/src/core/resources/data/minecraft/tags/item/boats.json new file mode 100644 index 0000000..8fbcbc0 --- /dev/null +++ b/src/core/resources/data/minecraft/tags/item/boats.json @@ -0,0 +1,8 @@ +{ + "values": [ + { + "required": false, + "id": "wild_wind_core:azalea_boat" + } + ] +} diff --git a/src/core/resources/data/minecraft/tags/item/buttons.json b/src/core/resources/data/minecraft/tags/item/buttons.json new file mode 100644 index 0000000..e116c67 --- /dev/null +++ b/src/core/resources/data/minecraft/tags/item/buttons.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:azalea_button" + ] +} diff --git a/src/core/resources/data/minecraft/tags/item/chest_boats.json b/src/core/resources/data/minecraft/tags/item/chest_boats.json new file mode 100644 index 0000000..1b61632 --- /dev/null +++ b/src/core/resources/data/minecraft/tags/item/chest_boats.json @@ -0,0 +1,8 @@ +{ + "values": [ + { + "required": false, + "id": "wild_wind_core:azalea_chest_boat" + } + ] +} diff --git a/src/core/resources/data/minecraft/tags/item/doors.json b/src/core/resources/data/minecraft/tags/item/doors.json new file mode 100644 index 0000000..ec33762 --- /dev/null +++ b/src/core/resources/data/minecraft/tags/item/doors.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:azalea_door" + ] +} diff --git a/src/core/resources/data/minecraft/tags/item/fence_gates.json b/src/core/resources/data/minecraft/tags/item/fence_gates.json new file mode 100644 index 0000000..5cecd6d --- /dev/null +++ b/src/core/resources/data/minecraft/tags/item/fence_gates.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:azalea_fence_gate" + ] +} diff --git a/src/core/resources/data/minecraft/tags/item/hanging_signs.json b/src/core/resources/data/minecraft/tags/item/hanging_signs.json new file mode 100644 index 0000000..b114ed6 --- /dev/null +++ b/src/core/resources/data/minecraft/tags/item/hanging_signs.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:azalea_hanging_sign" + ] +} diff --git a/src/core/resources/data/minecraft/tags/item/logs.json b/src/core/resources/data/minecraft/tags/item/logs.json new file mode 100644 index 0000000..8d968e5 --- /dev/null +++ b/src/core/resources/data/minecraft/tags/item/logs.json @@ -0,0 +1,8 @@ +{ + "values": [ + "wild_wind_core:azalea_log", + "wild_wind_core:azalea_wood", + "wild_wind_core:stripped_azalea_log", + "wild_wind_core:stripped_azalea_wood" + ] +} diff --git a/src/core/resources/data/minecraft/tags/item/logs_that_burn.json b/src/core/resources/data/minecraft/tags/item/logs_that_burn.json new file mode 100644 index 0000000..8d968e5 --- /dev/null +++ b/src/core/resources/data/minecraft/tags/item/logs_that_burn.json @@ -0,0 +1,8 @@ +{ + "values": [ + "wild_wind_core:azalea_log", + "wild_wind_core:azalea_wood", + "wild_wind_core:stripped_azalea_log", + "wild_wind_core:stripped_azalea_wood" + ] +} diff --git a/src/core/resources/data/minecraft/tags/item/planks.json b/src/core/resources/data/minecraft/tags/item/planks.json new file mode 100644 index 0000000..3a64f8f --- /dev/null +++ b/src/core/resources/data/minecraft/tags/item/planks.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:azalea_planks" + ] +} diff --git a/src/core/resources/data/minecraft/tags/item/signs.json b/src/core/resources/data/minecraft/tags/item/signs.json new file mode 100644 index 0000000..3d85148 --- /dev/null +++ b/src/core/resources/data/minecraft/tags/item/signs.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:azalea_sign" + ] +} diff --git a/src/core/resources/data/minecraft/tags/item/trapdoors.json b/src/core/resources/data/minecraft/tags/item/trapdoors.json new file mode 100644 index 0000000..3758f81 --- /dev/null +++ b/src/core/resources/data/minecraft/tags/item/trapdoors.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:azalea_trapdoor" + ] +} diff --git a/src/core/resources/data/minecraft/tags/item/wooden_buttons.json b/src/core/resources/data/minecraft/tags/item/wooden_buttons.json new file mode 100644 index 0000000..e116c67 --- /dev/null +++ b/src/core/resources/data/minecraft/tags/item/wooden_buttons.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:azalea_button" + ] +} diff --git a/src/core/resources/data/minecraft/tags/item/wooden_doors.json b/src/core/resources/data/minecraft/tags/item/wooden_doors.json new file mode 100644 index 0000000..ec33762 --- /dev/null +++ b/src/core/resources/data/minecraft/tags/item/wooden_doors.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:azalea_door" + ] +} diff --git a/src/core/resources/data/minecraft/tags/item/wooden_fences.json b/src/core/resources/data/minecraft/tags/item/wooden_fences.json new file mode 100644 index 0000000..6115af8 --- /dev/null +++ b/src/core/resources/data/minecraft/tags/item/wooden_fences.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:azalea_fence" + ] +} diff --git a/src/core/resources/data/minecraft/tags/item/wooden_pressure_plates.json b/src/core/resources/data/minecraft/tags/item/wooden_pressure_plates.json new file mode 100644 index 0000000..4cae1b8 --- /dev/null +++ b/src/core/resources/data/minecraft/tags/item/wooden_pressure_plates.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:azalea_pressure_plate" + ] +} diff --git a/src/core/resources/data/minecraft/tags/item/wooden_shelves.json b/src/core/resources/data/minecraft/tags/item/wooden_shelves.json new file mode 100644 index 0000000..83fd298 --- /dev/null +++ b/src/core/resources/data/minecraft/tags/item/wooden_shelves.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:azalea_shelf" + ] +} diff --git a/src/core/resources/data/minecraft/tags/item/wooden_slabs.json b/src/core/resources/data/minecraft/tags/item/wooden_slabs.json new file mode 100644 index 0000000..a1c4e5b --- /dev/null +++ b/src/core/resources/data/minecraft/tags/item/wooden_slabs.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:azalea_slab" + ] +} diff --git a/src/core/resources/data/minecraft/tags/item/wooden_stairs.json b/src/core/resources/data/minecraft/tags/item/wooden_stairs.json new file mode 100644 index 0000000..193f12f --- /dev/null +++ b/src/core/resources/data/minecraft/tags/item/wooden_stairs.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:azalea_stairs" + ] +} diff --git a/src/core/resources/data/minecraft/tags/item/wooden_trapdoors.json b/src/core/resources/data/minecraft/tags/item/wooden_trapdoors.json new file mode 100644 index 0000000..3758f81 --- /dev/null +++ b/src/core/resources/data/minecraft/tags/item/wooden_trapdoors.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_core:azalea_trapdoor" + ] +} diff --git a/src/core/resources/data/neoforge/data_maps/block/strippables.json b/src/core/resources/data/neoforge/data_maps/block/strippables.json new file mode 100644 index 0000000..1b86c5c --- /dev/null +++ b/src/core/resources/data/neoforge/data_maps/block/strippables.json @@ -0,0 +1,10 @@ +{ + "values": { + "wild_wind_core:azalea_log": { + "stripped_block": "wild_wind_core:stripped_azalea_log" + }, + "wild_wind_core:azalea_wood": { + "stripped_block": "wild_wind_core:stripped_azalea_wood" + } + } +} diff --git a/src/core/resources/data/wild_wind_core/advancement/recipes/building_blocks/azalea_planks.json b/src/core/resources/data/wild_wind_core/advancement/recipes/building_blocks/azalea_planks.json new file mode 100644 index 0000000..9e331cd --- /dev/null +++ b/src/core/resources/data/wild_wind_core/advancement/recipes/building_blocks/azalea_planks.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_azalea_log": { + "conditions": { + "items": [ + { + "items": "wild_wind_core:azalea_log" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "wild_wind_core:azalea_planks" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_azalea_log" + ] + ], + "rewards": { + "recipes": [ + "wild_wind_core:azalea_planks" + ] + } +} \ No newline at end of file diff --git a/src/core/resources/data/wild_wind_core/advancement/recipes/building_blocks/azalea_slab.json b/src/core/resources/data/wild_wind_core/advancement/recipes/building_blocks/azalea_slab.json new file mode 100644 index 0000000..2fec6ed --- /dev/null +++ b/src/core/resources/data/wild_wind_core/advancement/recipes/building_blocks/azalea_slab.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_azalea_planks": { + "conditions": { + "items": [ + { + "items": "wild_wind_core:azalea_planks" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "wild_wind_core:azalea_slab" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_azalea_planks" + ] + ], + "rewards": { + "recipes": [ + "wild_wind_core:azalea_slab" + ] + } +} \ No newline at end of file diff --git a/src/core/resources/data/wild_wind_core/advancement/recipes/building_blocks/azalea_stairs.json b/src/core/resources/data/wild_wind_core/advancement/recipes/building_blocks/azalea_stairs.json new file mode 100644 index 0000000..3454d42 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/advancement/recipes/building_blocks/azalea_stairs.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_azalea_planks": { + "conditions": { + "items": [ + { + "items": "wild_wind_core:azalea_planks" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "wild_wind_core:azalea_stairs" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_azalea_planks" + ] + ], + "rewards": { + "recipes": [ + "wild_wind_core:azalea_stairs" + ] + } +} \ No newline at end of file diff --git a/src/core/resources/data/wild_wind_core/advancement/recipes/building_blocks/azalea_wood.json b/src/core/resources/data/wild_wind_core/advancement/recipes/building_blocks/azalea_wood.json new file mode 100644 index 0000000..22ac123 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/advancement/recipes/building_blocks/azalea_wood.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_azalea_log": { + "conditions": { + "items": [ + { + "items": "wild_wind_core:azalea_log" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "wild_wind_core:azalea_wood" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_azalea_log" + ] + ], + "rewards": { + "recipes": [ + "wild_wind_core:azalea_wood" + ] + } +} \ No newline at end of file diff --git a/src/core/resources/data/wild_wind_core/advancement/recipes/decorations/azalea_fence.json b/src/core/resources/data/wild_wind_core/advancement/recipes/decorations/azalea_fence.json new file mode 100644 index 0000000..46f2182 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/advancement/recipes/decorations/azalea_fence.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_azalea_planks": { + "conditions": { + "items": [ + { + "items": "wild_wind_core:azalea_planks" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "wild_wind_core:azalea_fence" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_azalea_planks" + ] + ], + "rewards": { + "recipes": [ + "wild_wind_core:azalea_fence" + ] + } +} \ No newline at end of file diff --git a/src/core/resources/data/wild_wind_core/advancement/recipes/decorations/azalea_hanging_sign.json b/src/core/resources/data/wild_wind_core/advancement/recipes/decorations/azalea_hanging_sign.json new file mode 100644 index 0000000..00af81b --- /dev/null +++ b/src/core/resources/data/wild_wind_core/advancement/recipes/decorations/azalea_hanging_sign.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_stripped_azalea_log": { + "conditions": { + "items": [ + { + "items": "wild_wind_core:stripped_azalea_log" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "wild_wind_core:azalea_hanging_sign" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_stripped_azalea_log" + ] + ], + "rewards": { + "recipes": [ + "wild_wind_core:azalea_hanging_sign" + ] + } +} diff --git a/src/core/resources/data/wild_wind_core/advancement/recipes/decorations/azalea_shelf.json b/src/core/resources/data/wild_wind_core/advancement/recipes/decorations/azalea_shelf.json new file mode 100644 index 0000000..2996a00 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/advancement/recipes/decorations/azalea_shelf.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_stripped_azalea_log": { + "conditions": { + "items": [ + { + "items": "wild_wind_core:stripped_azalea_log" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "wild_wind_core:azalea_shelf" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_stripped_azalea_log" + ] + ], + "rewards": { + "recipes": [ + "wild_wind_core:azalea_shelf" + ] + } +} diff --git a/src/core/resources/data/wild_wind_core/advancement/recipes/decorations/azalea_sign.json b/src/core/resources/data/wild_wind_core/advancement/recipes/decorations/azalea_sign.json new file mode 100644 index 0000000..b5037e3 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/advancement/recipes/decorations/azalea_sign.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_azalea_planks": { + "conditions": { + "items": [ + { + "items": "wild_wind_core:azalea_planks" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "wild_wind_core:azalea_sign" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_azalea_planks" + ] + ], + "rewards": { + "recipes": [ + "wild_wind_core:azalea_sign" + ] + } +} diff --git a/src/core/resources/data/wild_wind_core/advancement/recipes/decorations/kiln.json b/src/core/resources/data/wild_wind_core/advancement/recipes/decorations/kiln.json new file mode 100644 index 0000000..b53190d --- /dev/null +++ b/src/core/resources/data/wild_wind_core/advancement/recipes/decorations/kiln.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_furnace": { + "conditions": { + "items": [ + { + "items": "minecraft:furnace" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "wild_wind_core:kiln" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_furnace" + ] + ], + "rewards": { + "recipes": [ + "wild_wind_core:kiln" + ] + } +} diff --git a/src/core/resources/data/wild_wind_core/advancement/recipes/redstone/azalea_button.json b/src/core/resources/data/wild_wind_core/advancement/recipes/redstone/azalea_button.json new file mode 100644 index 0000000..2b99cbc --- /dev/null +++ b/src/core/resources/data/wild_wind_core/advancement/recipes/redstone/azalea_button.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_azalea_planks": { + "conditions": { + "items": [ + { + "items": "wild_wind_core:azalea_planks" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "wild_wind_core:azalea_button" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_azalea_planks" + ] + ], + "rewards": { + "recipes": [ + "wild_wind_core:azalea_button" + ] + } +} \ No newline at end of file diff --git a/src/core/resources/data/wild_wind_core/advancement/recipes/redstone/azalea_door.json b/src/core/resources/data/wild_wind_core/advancement/recipes/redstone/azalea_door.json new file mode 100644 index 0000000..9af57b1 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/advancement/recipes/redstone/azalea_door.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_azalea_planks": { + "conditions": { + "items": [ + { + "items": "wild_wind_core:azalea_planks" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "wild_wind_core:azalea_door" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_azalea_planks" + ] + ], + "rewards": { + "recipes": [ + "wild_wind_core:azalea_door" + ] + } +} \ No newline at end of file diff --git a/src/core/resources/data/wild_wind_core/advancement/recipes/redstone/azalea_fence_gate.json b/src/core/resources/data/wild_wind_core/advancement/recipes/redstone/azalea_fence_gate.json new file mode 100644 index 0000000..93d4965 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/advancement/recipes/redstone/azalea_fence_gate.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_azalea_planks": { + "conditions": { + "items": [ + { + "items": "wild_wind_core:azalea_planks" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "wild_wind_core:azalea_fence_gate" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_azalea_planks" + ] + ], + "rewards": { + "recipes": [ + "wild_wind_core:azalea_fence_gate" + ] + } +} \ No newline at end of file diff --git a/src/core/resources/data/wild_wind_core/advancement/recipes/redstone/azalea_pressure_plate.json b/src/core/resources/data/wild_wind_core/advancement/recipes/redstone/azalea_pressure_plate.json new file mode 100644 index 0000000..d96e129 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/advancement/recipes/redstone/azalea_pressure_plate.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_azalea_planks": { + "conditions": { + "items": [ + { + "items": "wild_wind_core:azalea_planks" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "wild_wind_core:azalea_pressure_plate" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_azalea_planks" + ] + ], + "rewards": { + "recipes": [ + "wild_wind_core:azalea_pressure_plate" + ] + } +} \ No newline at end of file diff --git a/src/core/resources/data/wild_wind_core/advancement/recipes/redstone/azalea_trapdoor.json b/src/core/resources/data/wild_wind_core/advancement/recipes/redstone/azalea_trapdoor.json new file mode 100644 index 0000000..ea50938 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/advancement/recipes/redstone/azalea_trapdoor.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_azalea_planks": { + "conditions": { + "items": [ + { + "items": "wild_wind_core:azalea_planks" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "wild_wind_core:azalea_trapdoor" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_azalea_planks" + ] + ], + "rewards": { + "recipes": [ + "wild_wind_core:azalea_trapdoor" + ] + } +} \ No newline at end of file diff --git a/src/core/resources/data/wild_wind_core/enchantment/melting.json b/src/core/resources/data/wild_wind_core/enchantment/melting.json new file mode 100644 index 0000000..d361834 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/enchantment/melting.json @@ -0,0 +1,21 @@ +{ + "description": { + "translate": "enchantment.wild_wind_core.melting" + }, + "supported_items": "#minecraft:enchantable/mining", + "weight": 2, + "max_level": 1, + "min_cost": { + "base": 15, + "per_level_above_first": 0 + }, + "max_cost": { + "base": 65, + "per_level_above_first": 0 + }, + "anvil_cost": 4, + "slots": [ + "mainhand" + ], + "effects": {} +} diff --git a/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_button.json b/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_button.json new file mode 100644 index 0000000..72f2930 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_button.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_core:azalea_button" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_core:blocks/azalea_button" +} diff --git a/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_door.json b/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_door.json new file mode 100644 index 0000000..e10fcd4 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_door.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "conditions": [ + { + "block": "wild_wind_core:azalea_door", + "condition": "minecraft:block_state_property", + "properties": { + "half": "lower" + } + } + ], + "name": "wild_wind_core:azalea_door" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_core:blocks/azalea_door" +} diff --git a/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_fence.json b/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_fence.json new file mode 100644 index 0000000..eeab666 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_fence.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_core:azalea_fence" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_core:blocks/azalea_fence" +} diff --git a/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_fence_gate.json b/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_fence_gate.json new file mode 100644 index 0000000..c0d7f71 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_fence_gate.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_core:azalea_fence_gate" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_core:blocks/azalea_fence_gate" +} diff --git a/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_hanging_sign.json b/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_hanging_sign.json new file mode 100644 index 0000000..cf89a67 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_hanging_sign.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_core:azalea_hanging_sign" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_core:blocks/azalea_hanging_sign" +} diff --git a/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_log.json b/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_log.json new file mode 100644 index 0000000..d012fd2 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_log.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_core:azalea_log" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_core:blocks/azalea_log" +} diff --git a/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_planks.json b/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_planks.json new file mode 100644 index 0000000..f48ca12 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_planks.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_core:azalea_planks" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_core:blocks/azalea_planks" +} diff --git a/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_pressure_plate.json b/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_pressure_plate.json new file mode 100644 index 0000000..36185c4 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_pressure_plate.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_core:azalea_pressure_plate" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_core:blocks/azalea_pressure_plate" +} diff --git a/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_shelf.json b/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_shelf.json new file mode 100644 index 0000000..5f4bd82 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_shelf.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_core:azalea_shelf" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_core:blocks/azalea_shelf" +} diff --git a/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_sign.json b/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_sign.json new file mode 100644 index 0000000..2af5402 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_sign.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_core:azalea_sign" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_core:blocks/azalea_sign" +} diff --git a/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_slab.json b/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_slab.json new file mode 100644 index 0000000..155514f --- /dev/null +++ b/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_slab.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_core:azalea_slab" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_core:blocks/azalea_slab" +} diff --git a/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_stairs.json b/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_stairs.json new file mode 100644 index 0000000..b60ecc2 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_stairs.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_core:azalea_stairs" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_core:blocks/azalea_stairs" +} diff --git a/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_trapdoor.json b/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_trapdoor.json new file mode 100644 index 0000000..2dbb149 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_trapdoor.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_core:azalea_trapdoor" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_core:blocks/azalea_trapdoor" +} diff --git a/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_wall_hanging_sign.json b/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_wall_hanging_sign.json new file mode 100644 index 0000000..161609b --- /dev/null +++ b/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_wall_hanging_sign.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_core:azalea_hanging_sign" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_core:blocks/azalea_wall_hanging_sign" +} \ No newline at end of file diff --git a/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_wall_sign.json b/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_wall_sign.json new file mode 100644 index 0000000..f513ec8 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_wall_sign.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_core:azalea_sign" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_core:blocks/azalea_wall_sign" +} \ No newline at end of file diff --git a/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_wood.json b/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_wood.json new file mode 100644 index 0000000..ca7cf42 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/loot_table/blocks/azalea_wood.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_core:azalea_wood" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_core:blocks/azalea_wood" +} diff --git a/src/core/resources/data/wild_wind_core/loot_table/blocks/kiln.json b/src/core/resources/data/wild_wind_core/loot_table/blocks/kiln.json new file mode 100644 index 0000000..ade5c3d --- /dev/null +++ b/src/core/resources/data/wild_wind_core/loot_table/blocks/kiln.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:copy_components", + "include": [ + "minecraft:custom_name" + ], + "source": "block_entity" + } + ], + "name": "wild_wind_core:kiln" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_core:blocks/kiln" +} diff --git a/src/core/resources/data/wild_wind_core/loot_table/blocks/stripped_azalea_log.json b/src/core/resources/data/wild_wind_core/loot_table/blocks/stripped_azalea_log.json new file mode 100644 index 0000000..953ff6a --- /dev/null +++ b/src/core/resources/data/wild_wind_core/loot_table/blocks/stripped_azalea_log.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_core:stripped_azalea_log" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_core:blocks/stripped_azalea_log" +} diff --git a/src/core/resources/data/wild_wind_core/loot_table/blocks/stripped_azalea_wood.json b/src/core/resources/data/wild_wind_core/loot_table/blocks/stripped_azalea_wood.json new file mode 100644 index 0000000..00e6538 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/loot_table/blocks/stripped_azalea_wood.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_core:stripped_azalea_wood" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_core:blocks/stripped_azalea_wood" +} diff --git a/src/core/resources/data/wild_wind_core/neoforge/biome_modifier/add_azalea_tree.json b/src/core/resources/data/wild_wind_core/neoforge/biome_modifier/add_azalea_tree.json new file mode 100644 index 0000000..0f39991 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/neoforge/biome_modifier/add_azalea_tree.json @@ -0,0 +1,6 @@ +{ + "type": "neoforge:add_features", + "biomes": "minecraft:lush_caves", + "features": "wild_wind_core:azalea_tree_placed", + "step": "vegetal_decoration" +} diff --git a/src/core/resources/data/wild_wind_core/neoforge/biome_modifier/remove_vanilla_azalea_tree.json b/src/core/resources/data/wild_wind_core/neoforge/biome_modifier/remove_vanilla_azalea_tree.json new file mode 100644 index 0000000..362d5c6 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/neoforge/biome_modifier/remove_vanilla_azalea_tree.json @@ -0,0 +1,6 @@ +{ + "type": "neoforge:remove_features", + "biomes": "minecraft:lush_caves", + "features": "minecraft:rooted_azalea_tree", + "steps": "vegetal_decoration" +} diff --git a/src/core/resources/data/wild_wind_core/recipe/azalea_button.json b/src/core/resources/data/wild_wind_core/recipe/azalea_button.json new file mode 100644 index 0000000..4ca3360 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/recipe/azalea_button.json @@ -0,0 +1,10 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "redstone", + "ingredients": [ + "wild_wind_core:azalea_planks" + ], + "result": { + "id": "wild_wind_core:azalea_button" + } +} \ No newline at end of file diff --git a/src/core/resources/data/wild_wind_core/recipe/azalea_door.json b/src/core/resources/data/wild_wind_core/recipe/azalea_door.json new file mode 100644 index 0000000..6c1ffe5 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/recipe/azalea_door.json @@ -0,0 +1,16 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "redstone", + "key": { + "#": "wild_wind_core:azalea_planks" + }, + "pattern": [ + "##", + "##", + "##" + ], + "result": { + "count": 3, + "id": "wild_wind_core:azalea_door" + } +} \ No newline at end of file diff --git a/src/core/resources/data/wild_wind_core/recipe/azalea_fence.json b/src/core/resources/data/wild_wind_core/recipe/azalea_fence.json new file mode 100644 index 0000000..9adb175 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/recipe/azalea_fence.json @@ -0,0 +1,15 @@ +{ + "type": "minecraft:crafting_shaped", + "key": { + "#": "minecraft:stick", + "W": "wild_wind_core:azalea_planks" + }, + "pattern": [ + "W#W", + "W#W" + ], + "result": { + "count": 3, + "id": "wild_wind_core:azalea_fence" + } +} \ No newline at end of file diff --git a/src/core/resources/data/wild_wind_core/recipe/azalea_fence_gate.json b/src/core/resources/data/wild_wind_core/recipe/azalea_fence_gate.json new file mode 100644 index 0000000..29851aa --- /dev/null +++ b/src/core/resources/data/wild_wind_core/recipe/azalea_fence_gate.json @@ -0,0 +1,15 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "redstone", + "key": { + "#": "minecraft:stick", + "W": "wild_wind_core:azalea_planks" + }, + "pattern": [ + "#W#", + "#W#" + ], + "result": { + "id": "wild_wind_core:azalea_fence_gate" + } +} \ No newline at end of file diff --git a/src/core/resources/data/wild_wind_core/recipe/azalea_hanging_sign.json b/src/core/resources/data/wild_wind_core/recipe/azalea_hanging_sign.json new file mode 100644 index 0000000..f9a26e7 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/recipe/azalea_hanging_sign.json @@ -0,0 +1,16 @@ +{ + "type": "minecraft:crafting_shaped", + "key": { + "C": "minecraft:iron_chain", + "L": "wild_wind_core:stripped_azalea_log" + }, + "pattern": [ + "C C", + "LLL", + "LLL" + ], + "result": { + "count": 6, + "id": "wild_wind_core:azalea_hanging_sign" + } +} diff --git a/src/core/resources/data/wild_wind_core/recipe/azalea_planks.json b/src/core/resources/data/wild_wind_core/recipe/azalea_planks.json new file mode 100644 index 0000000..1f287ef --- /dev/null +++ b/src/core/resources/data/wild_wind_core/recipe/azalea_planks.json @@ -0,0 +1,12 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "planks", + "ingredients": [ + "wild_wind_core:azalea_log" + ], + "result": { + "count": 4, + "id": "wild_wind_core:azalea_planks" + } +} \ No newline at end of file diff --git a/src/core/resources/data/wild_wind_core/recipe/azalea_pressure_plate.json b/src/core/resources/data/wild_wind_core/recipe/azalea_pressure_plate.json new file mode 100644 index 0000000..cefa0aa --- /dev/null +++ b/src/core/resources/data/wild_wind_core/recipe/azalea_pressure_plate.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "redstone", + "key": { + "#": "wild_wind_core:azalea_planks" + }, + "pattern": [ + "##" + ], + "result": { + "id": "wild_wind_core:azalea_pressure_plate" + } +} \ No newline at end of file diff --git a/src/core/resources/data/wild_wind_core/recipe/azalea_shelf.json b/src/core/resources/data/wild_wind_core/recipe/azalea_shelf.json new file mode 100644 index 0000000..9cdbdfb --- /dev/null +++ b/src/core/resources/data/wild_wind_core/recipe/azalea_shelf.json @@ -0,0 +1,15 @@ +{ + "type": "minecraft:crafting_shaped", + "key": { + "L": "wild_wind_core:stripped_azalea_log" + }, + "pattern": [ + "LLL", + " ", + "LLL" + ], + "result": { + "count": 6, + "id": "wild_wind_core:azalea_shelf" + } +} diff --git a/src/core/resources/data/wild_wind_core/recipe/azalea_sign.json b/src/core/resources/data/wild_wind_core/recipe/azalea_sign.json new file mode 100644 index 0000000..d5ed29e --- /dev/null +++ b/src/core/resources/data/wild_wind_core/recipe/azalea_sign.json @@ -0,0 +1,16 @@ +{ + "type": "minecraft:crafting_shaped", + "key": { + "P": "wild_wind_core:azalea_planks", + "S": "minecraft:stick" + }, + "pattern": [ + "PPP", + "PPP", + " S " + ], + "result": { + "count": 3, + "id": "wild_wind_core:azalea_sign" + } +} diff --git a/src/core/resources/data/wild_wind_core/recipe/azalea_slab.json b/src/core/resources/data/wild_wind_core/recipe/azalea_slab.json new file mode 100644 index 0000000..07e255f --- /dev/null +++ b/src/core/resources/data/wild_wind_core/recipe/azalea_slab.json @@ -0,0 +1,14 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "key": { + "#": "wild_wind_core:azalea_planks" + }, + "pattern": [ + "###" + ], + "result": { + "count": 6, + "id": "wild_wind_core:azalea_slab" + } +} \ No newline at end of file diff --git a/src/core/resources/data/wild_wind_core/recipe/azalea_stairs.json b/src/core/resources/data/wild_wind_core/recipe/azalea_stairs.json new file mode 100644 index 0000000..04934ff --- /dev/null +++ b/src/core/resources/data/wild_wind_core/recipe/azalea_stairs.json @@ -0,0 +1,16 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "key": { + "#": "wild_wind_core:azalea_planks" + }, + "pattern": [ + "# ", + "## ", + "###" + ], + "result": { + "count": 4, + "id": "wild_wind_core:azalea_stairs" + } +} \ No newline at end of file diff --git a/src/core/resources/data/wild_wind_core/recipe/azalea_trapdoor.json b/src/core/resources/data/wild_wind_core/recipe/azalea_trapdoor.json new file mode 100644 index 0000000..4462315 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/recipe/azalea_trapdoor.json @@ -0,0 +1,15 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "redstone", + "key": { + "#": "wild_wind_core:azalea_planks" + }, + "pattern": [ + "###", + "###" + ], + "result": { + "count": 2, + "id": "wild_wind_core:azalea_trapdoor" + } +} \ No newline at end of file diff --git a/src/core/resources/data/wild_wind_core/recipe/azalea_wood.json b/src/core/resources/data/wild_wind_core/recipe/azalea_wood.json new file mode 100644 index 0000000..970cf09 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/recipe/azalea_wood.json @@ -0,0 +1,15 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "key": { + "#": "wild_wind_core:azalea_log" + }, + "pattern": [ + "##", + "##" + ], + "result": { + "count": 3, + "id": "wild_wind_core:azalea_wood" + } +} \ No newline at end of file diff --git a/src/core/resources/data/wild_wind_core/recipe/kiln.json b/src/core/resources/data/wild_wind_core/recipe/kiln.json new file mode 100644 index 0000000..b12ba71 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/recipe/kiln.json @@ -0,0 +1,16 @@ +{ + "type": "minecraft:crafting_shaped", + "key": { + "B": "minecraft:brick", + "F": "minecraft:furnace", + "M": "minecraft:packed_mud" + }, + "pattern": [ + " B ", + "BFB", + "MMM" + ], + "result": { + "id": "wild_wind_core:kiln" + } +} diff --git a/src/core/resources/data/wild_wind_core/recipe/wool_to_string.json b/src/core/resources/data/wild_wind_core/recipe/wool_to_string.json new file mode 100644 index 0000000..3526fa2 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/recipe/wool_to_string.json @@ -0,0 +1,3 @@ +{ + "type": "wild_wind_core:wool_to_string" +} diff --git a/src/core/resources/data/wild_wind_core/tags/block/azalea_logs.json b/src/core/resources/data/wild_wind_core/tags/block/azalea_logs.json new file mode 100644 index 0000000..ea58888 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/tags/block/azalea_logs.json @@ -0,0 +1,8 @@ +{ + "values": [ + "wild_wind_core:azalea_log", + "wild_wind_core:azalea_wood", + "wild_wind_core:stripped_azalea_log", + "wild_wind_core:stripped_azalea_wood" + ] +} \ No newline at end of file diff --git a/src/core/resources/data/wild_wind_core/tags/entity_type/inspection/renewable.json b/src/core/resources/data/wild_wind_core/tags/entity_type/inspection/renewable.json new file mode 100644 index 0000000..34b808a --- /dev/null +++ b/src/core/resources/data/wild_wind_core/tags/entity_type/inspection/renewable.json @@ -0,0 +1,44 @@ +{ + "replace": false, + "values": [ + "minecraft:cow", + "minecraft:pig", + "minecraft:sheep", + "minecraft:chicken", + "minecraft:mooshroom", + "minecraft:horse", + "minecraft:donkey", + "minecraft:mule", + "minecraft:rabbit", + "minecraft:wolf", + "minecraft:cat", + "minecraft:ocelot", + "minecraft:llama", + "minecraft:camel", + "minecraft:goat", + "minecraft:fox", + "minecraft:panda", + "minecraft:bee", + "minecraft:turtle", + "minecraft:frog", + "minecraft:tadpole", + "minecraft:axolotl", + "minecraft:villager", + "minecraft:iron_golem", + "minecraft:snow_golem", + "minecraft:zombie", + "minecraft:skeleton", + "minecraft:creeper", + "minecraft:spider", + "minecraft:cave_spider", + "minecraft:slime", + "minecraft:magma_cube", + "minecraft:drowned", + "minecraft:squid", + "minecraft:glow_squid", + "minecraft:cod", + "minecraft:salmon", + "minecraft:pufferfish", + "minecraft:tropical_fish" + ] +} diff --git a/src/core/resources/data/wild_wind_core/tags/item/azalea_logs.json b/src/core/resources/data/wild_wind_core/tags/item/azalea_logs.json new file mode 100644 index 0000000..8d968e5 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/tags/item/azalea_logs.json @@ -0,0 +1,8 @@ +{ + "values": [ + "wild_wind_core:azalea_log", + "wild_wind_core:azalea_wood", + "wild_wind_core:stripped_azalea_log", + "wild_wind_core:stripped_azalea_wood" + ] +} diff --git a/src/core/resources/data/wild_wind_core/tags/item/inspection/non_renewable.json b/src/core/resources/data/wild_wind_core/tags/item/inspection/non_renewable.json new file mode 100644 index 0000000..15f807d --- /dev/null +++ b/src/core/resources/data/wild_wind_core/tags/item/inspection/non_renewable.json @@ -0,0 +1,15 @@ +{ + "replace": false, + "values": [ + "minecraft:ancient_debris", + "minecraft:netherite_scrap", + "minecraft:netherite_ingot", + "minecraft:netherite_block", + "minecraft:diamond", + "minecraft:diamond_block", + "minecraft:deepslate", + "minecraft:raw_gold_block", + "minecraft:raw_iron_block", + "minecraft:raw_copper_block" + ] +} diff --git a/src/core/resources/data/wild_wind_core/tags/item/inspection/renewable.json b/src/core/resources/data/wild_wind_core/tags/item/inspection/renewable.json new file mode 100644 index 0000000..a167881 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/tags/item/inspection/renewable.json @@ -0,0 +1,50 @@ +{ + "replace": false, + "values": [ + "#minecraft:logs", + "#minecraft:planks", + "#minecraft:wool", + "#minecraft:saplings", + "#minecraft:leaves", + "#minecraft:wooden_slabs", + "#minecraft:wooden_stairs", + "#minecraft:wooden_fences", + "#minecraft:wooden_doors", + "#minecraft:wooden_trapdoors", + "#minecraft:wooden_buttons", + "#minecraft:wooden_pressure_plates", + "#minecraft:signs", + "#minecraft:hanging_signs", + "minecraft:stone", + "minecraft:cobblestone", + "minecraft:obsidian", + "minecraft:basalt", + "minecraft:blackstone", + "minecraft:ice", + "minecraft:packed_ice", + "minecraft:blue_ice", + "minecraft:snow_block", + "minecraft:clay", + "minecraft:mud", + "minecraft:dirt", + "minecraft:grass_block", + "minecraft:moss_block", + "minecraft:honey_block", + "minecraft:slime_block", + "minecraft:iron_block", + "minecraft:gold_block", + "minecraft:copper_block", + "minecraft:emerald_block", + "minecraft:redstone_block", + "minecraft:coal", + "minecraft:charcoal", + "minecraft:stick", + "minecraft:string", + "minecraft:egg", + "minecraft:cactus", + "minecraft:sugar_cane", + "minecraft:bamboo", + "minecraft:kelp", + "wild_wind_core:azalea_shelf" + ] +} diff --git a/src/core/resources/data/wild_wind_core/tags/item/kiln_excluded.json b/src/core/resources/data/wild_wind_core/tags/item/kiln_excluded.json new file mode 100644 index 0000000..dce14ed --- /dev/null +++ b/src/core/resources/data/wild_wind_core/tags/item/kiln_excluded.json @@ -0,0 +1,10 @@ +{ + "replace": false, + "values": [ + { "id": "#c:ores", "required": false }, + { "id": "#c:raw_materials", "required": false }, + { "id": "#c:ingots", "required": false }, + { "id": "#c:nuggets", "required": false }, + { "id": "#c:gems", "required": false } + ] +} diff --git a/src/core/resources/data/wild_wind_core/tags/item/kiln_metal_outputs.json b/src/core/resources/data/wild_wind_core/tags/item/kiln_metal_outputs.json new file mode 100644 index 0000000..d5fb4b7 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/tags/item/kiln_metal_outputs.json @@ -0,0 +1,7 @@ +{ + "replace": false, + "values": [ + { "id": "#c:ingots", "required": false }, + { "id": "#c:nuggets", "required": false } + ] +} diff --git a/src/core/resources/data/wild_wind_core/worldgen/configured_feature/azalea_tree.json b/src/core/resources/data/wild_wind_core/worldgen/configured_feature/azalea_tree.json new file mode 100644 index 0000000..d903ef3 --- /dev/null +++ b/src/core/resources/data/wild_wind_core/worldgen/configured_feature/azalea_tree.json @@ -0,0 +1,71 @@ +{ + "type": "minecraft:tree", + "config": { + "below_trunk_provider": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "minecraft:rooted_dirt" + } + }, + "decorators": [], + "foliage_placer": { + "type": "minecraft:random_spread_foliage_placer", + "foliage_height": 2, + "leaf_placement_attempts": 50, + "offset": 0, + "radius": 3 + }, + "foliage_provider": { + "type": "minecraft:weighted_state_provider", + "entries": [ + { + "data": { + "Name": "minecraft:azalea_leaves", + "Properties": { + "distance": "7", + "persistent": "false", + "waterlogged": "false" + } + }, + "weight": 3 + }, + { + "data": { + "Name": "minecraft:flowering_azalea_leaves", + "Properties": { + "distance": "7", + "persistent": "false", + "waterlogged": "false" + } + }, + "weight": 1 + } + ] + }, + "ignore_vines": false, + "minimum_size": { + "type": "minecraft:two_layers_feature_size" + }, + "trunk_placer": { + "type": "minecraft:bending_trunk_placer", + "base_height": 4, + "bend_length": { + "type": "minecraft:uniform", + "max_inclusive": 2, + "min_inclusive": 1 + }, + "height_rand_a": 2, + "height_rand_b": 0, + "min_height_for_leaves": 3 + }, + "trunk_provider": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "wild_wind_core:azalea_log", + "Properties": { + "axis": "y" + } + } + } + } +} diff --git a/src/core/resources/data/wild_wind_core/worldgen/placed_feature/azalea_tree_placed.json b/src/core/resources/data/wild_wind_core/worldgen/placed_feature/azalea_tree_placed.json new file mode 100644 index 0000000..0332bff --- /dev/null +++ b/src/core/resources/data/wild_wind_core/worldgen/placed_feature/azalea_tree_placed.json @@ -0,0 +1,48 @@ +{ + "feature": "wild_wind_core:azalea_tree", + "placement": [ + { + "type": "minecraft:count", + "count": { + "type": "minecraft:uniform", + "max_inclusive": 2, + "min_inclusive": 1 + } + }, + { + "type": "minecraft:in_square" + }, + { + "type": "minecraft:height_range", + "height": { + "type": "minecraft:uniform", + "max_inclusive": { + "absolute": 256 + }, + "min_inclusive": { + "above_bottom": 0 + } + } + }, + { + "type": "minecraft:environment_scan", + "allowed_search_condition": { + "type": "minecraft:matching_block_tag", + "tag": "minecraft:air" + }, + "direction_of_search": "up", + "max_steps": 12, + "target_condition": { + "type": "minecraft:solid" + } + }, + { + "type": "minecraft:random_offset", + "xz_spread": 0, + "y_spread": -1 + }, + { + "type": "minecraft:biome" + } + ] +} diff --git a/src/core/resources/examples/example_ruins.json b/src/core/resources/examples/example_ruins.json new file mode 100644 index 0000000..1bc47cf --- /dev/null +++ b/src/core/resources/examples/example_ruins.json @@ -0,0 +1,23 @@ +{ + "name": "example_ruins", + "enabled": false, + "template": "example_ruins.nbt", + "biomes": ["minecraft:plains", "#minecraft:is_forest"], + "placement": { + "spacing": 32, + "separation": 8, + "salt": 18372954, + "frequency": 1.0 + }, + "heightmap": "WORLD_SURFACE_WG", + "y_offset": -1, + "rotation": "random", + "include_entities": false, + "conditions": { + "min_y": 60, + "max_y": 160, + "max_terrain_difference": 6, + "avoid_fluids": true, + "ground_blocks": ["#minecraft:dirt", "minecraft:stone", "minecraft:sand"] + } +} diff --git a/src/core/resources/examples/example_ruins.nbt b/src/core/resources/examples/example_ruins.nbt new file mode 100644 index 0000000..30160f9 Binary files /dev/null and b/src/core/resources/examples/example_ruins.nbt differ diff --git a/src/core/resources/wild_wind_core.mixins.json b/src/core/resources/wild_wind_core.mixins.json new file mode 100644 index 0000000..39c2046 --- /dev/null +++ b/src/core/resources/wild_wind_core.mixins.json @@ -0,0 +1,23 @@ +{ + "required": true, + "package": "org.polaris2023.wildwind.core.mixin", + "compatibilityLevel": "JAVA_25", + "mixins": [ + "FurnaceFuelAccessor", + "SinglePoolElementMixin", + "AbstractSkeletonMixin", + "AzaleaBlockMixin", + "CrafterBlockMixin", + "SkeletonMeleeMixin" + ], + "injectors": { + "defaultRequire": 1 + }, + "overwrites": { + "requireAnnotations": true + }, + "client": [ + "SignRenderStateMixin", + "AzaleaSignRendererMixin" + ] +} diff --git a/src/core/test/org/polaris2023/wildwind/core/inspection/BookPagesTest.java b/src/core/test/org/polaris2023/wildwind/core/inspection/BookPagesTest.java new file mode 100644 index 0000000..ec9a346 --- /dev/null +++ b/src/core/test/org/polaris2023/wildwind/core/inspection/BookPagesTest.java @@ -0,0 +1,22 @@ +package org.polaris2023.wildwind.core.inspection; + +import java.util.List; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +class BookPagesTest { + @Test + void wrapsLongMixedLanguageIdsWithoutLosingCharactersOrOverflowingPages() { + String row = "物品ID:wild_wind_wilderness:very_long_item_" + "测试".repeat(1000) + "😀"; + var pages = BookPages.paginate(List.of(row)); + assertTrue(pages.size() > 1); + assertEquals(row, String.join("", pages).replace("\n", "")); + for (String page : pages) { + assertTrue(page.length() <= 1024); + assertTrue(page.split("\n", -1).length <= 12); + for (String line : page.split("\n", -1)) { + assertTrue(line.codePoints().map(cp -> cp >= 32 && cp < 127 ? 6 : 10).sum() <= 108); + } + } + } +} diff --git a/src/core/test/org/polaris2023/wildwind/structures/config/StructureConfigTest.java b/src/core/test/org/polaris2023/wildwind/structures/config/StructureConfigTest.java new file mode 100644 index 0000000..ca4f032 --- /dev/null +++ b/src/core/test/org/polaris2023/wildwind/structures/config/StructureConfigTest.java @@ -0,0 +1,137 @@ +package org.polaris2023.wildwind.structures.config; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import java.io.ByteArrayOutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HashMap; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.IntTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.NbtIo; +import net.minecraft.resources.Identifier; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import static org.junit.jupiter.api.Assertions.*; + +class StructureConfigTest { + @TempDir Path directory; + + private static JsonObject definition() { + return JsonParser.parseString(""" + {"name":"ruins", "template":"ruins.nbt", "biomes":["minecraft:plains", "#minecraft:is_forest"]} + """).getAsJsonObject(); + } + + @Test void defaultsAndNamespacedBiomeTags() { + var config = StructureDefinition.parse(definition()); + assertEquals(32, config.spacing()); + assertEquals(8, config.separation()); + assertEquals("#minecraft:is_forest", config.biomes().get(1)); + assertFalse(config.includeEntities()); + assertTrue(config.conditions().avoidFluids()); + } + + @Test void rejectsInvalidPlacementAndMistypedOptions() { + for (String placement : new String[]{"{\"spacing\":8,\"separation\":8}", "{\"frequency\":0}", + "{\"frequency\":1.1}", "{\"spacing\":32.5}", "{\"salt\":-1}", "{\"spacing\":\"32\"}"}) { + JsonObject json = definition(); + json.add("placement", JsonParser.parseString(placement)); + assertThrows(IllegalArgumentException.class, () -> StructureDefinition.parse(json)); + } + JsonObject typo = definition(); + typo.addProperty("y_offest", 5); + assertThrows(IllegalArgumentException.class, () -> StructureDefinition.parse(typo)); + JsonObject booleanString = definition(); + booleanString.addProperty("include_entities", "false"); + assertThrows(IllegalArgumentException.class, () -> StructureDefinition.parse(booleanString)); + } + + @Test void rejectsInvalidNamesBiomesAndHeightRanges() { + for (String name : new String[]{"../escape", "MixedCase", "a:b", ""}) { + JsonObject json = definition(); + json.addProperty("name", name); + assertThrows(IllegalArgumentException.class, () -> StructureDefinition.parse(json)); + } + JsonObject emptyBiomes = definition(); + emptyBiomes.add("biomes", JsonParser.parseString("[]")); + assertThrows(IllegalArgumentException.class, () -> StructureDefinition.parse(emptyBiomes)); + JsonObject json = definition(); + json.add("conditions", JsonParser.parseString("{\"min_y\":100,\"max_y\":80}")); + JsonObject invalidHeight = json; + assertThrows(IllegalArgumentException.class, () -> StructureDefinition.parse(invalidHeight)); + } + + @Test void templatePathsStayInsideDirectory() throws Exception { + Path templates = Files.createDirectories(directory.resolve("templates")); + Files.write(templates.resolve("ruins.nbt"), new byte[0]); + assertEquals(templates.resolve("ruins.nbt").toRealPath(), StructureDefinition.parse(definition()).resolveTemplate(templates)); + for (String path : new String[]{"../escape.nbt", "C:/escape.nbt", "/escape.nbt", "..\\escape.nbt"}) { + JsonObject json = definition(); + json.addProperty("template", path); + var parsed = StructureDefinition.parse(json); + assertThrows(IllegalArgumentException.class, () -> parsed.resolveTemplate(templates)); + } + } + + @Test void disabledStructuresKeepTemplatesButNotPlacementAndDuplicateNamesFail() throws Exception { + ConfigStructurePack.load(directory); + Path definitions = directory.resolve("definitions"); + JsonObject disabled = definition(); + disabled.addProperty("enabled", false); + Files.writeString(definitions.resolve("disabled.json"), disabled.toString()); + Files.write(directory.resolve("templates/ruins.nbt"), template(3, 2, 3)); + var disabledResources = ConfigStructurePack.load(directory); + assertEquals(3, disabledResources.size()); + assertTrue(disabledResources.containsKey(Identifier.parse("ww_structures:structure/ruins.nbt"))); + assertFalse(disabledResources.containsKey(Identifier.parse("ww_structures:worldgen/structure_set/ruins.json"))); + Files.writeString(definitions.resolve("disabled.json"), definition().toString()); + var resources = ConfigStructurePack.load(directory); + assertEquals(4, resources.size()); + Files.writeString(definitions.resolve("b.json"), definition().toString()); + var error = assertThrows(java.io.IOException.class, () -> ConfigStructurePack.load(directory)); + assertTrue(error.getMessage().contains("Duplicate name")); + } + + @Test void packContainsTemplateBiomeTagAndRandomSpreadRule() { + var resources = new HashMap(); + byte[] template = {1, 2, 3}; + ConfigStructurePack.addDefinition(resources, StructureDefinition.parse(definition()), template); + assertArrayEquals(template, resources.get(Identifier.parse("ww_structures:structure/ruins.nbt"))); + var placement = JsonParser.parseString(new String(resources.get(Identifier.parse("ww_structures:worldgen/structure_set/ruins.json")), + java.nio.charset.StandardCharsets.UTF_8)).getAsJsonObject().getAsJsonObject("placement"); + assertEquals("minecraft:random_spread", placement.get("type").getAsString()); + assertEquals(32, placement.get("spacing").getAsInt()); + } + + @Test void rejectsMalformedOrOversizeTemplate() throws Exception { + ConfigStructurePack.validateTemplate(template(3, 2, 3)); + assertThrows(java.io.IOException.class, () -> ConfigStructurePack.validateTemplate(new byte[]{1, 2, 3})); + assertThrows(java.io.IOException.class, () -> ConfigStructurePack.validateTemplate(template(65, 2, 3))); + assertThrows(java.io.IOException.class, () -> ConfigStructurePack.validateTemplate(template(3, 0, 3))); + } + + private static byte[] template(int x, int y, int z) throws Exception { + CompoundTag root = new CompoundTag(); + ListTag size = new ListTag(); + size.add(IntTag.valueOf(x)); size.add(IntTag.valueOf(y)); size.add(IntTag.valueOf(z)); + root.put("size", size); + ListTag blocks = new ListTag(); + CompoundTag block = new CompoundTag(); + block.putInt("state", 0); + ListTag pos = new ListTag(); + for (int i = 0; i < 3; i++) pos.add(IntTag.valueOf(0)); + block.put("pos", pos); + blocks.add(block); + root.put("blocks", blocks); + ListTag palette = new ListTag(); + CompoundTag stone = new CompoundTag(); + stone.putString("Name", "minecraft:stone"); + palette.add(stone); + root.put("palette", palette); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + NbtIo.writeCompressed(root, out); + return out.toByteArray(); + } +} diff --git a/src/core/test/org/polaris2023/wildwind/structures/worldgen/GeneratedStructureIndexTest.java b/src/core/test/org/polaris2023/wildwind/structures/worldgen/GeneratedStructureIndexTest.java new file mode 100644 index 0000000..bb4888d --- /dev/null +++ b/src/core/test/org/polaris2023/wildwind/structures/worldgen/GeneratedStructureIndexTest.java @@ -0,0 +1,29 @@ +package org.polaris2023.wildwind.structures.worldgen; + +import com.mojang.serialization.JsonOps; +import net.minecraft.core.BlockPos; +import net.minecraft.resources.Identifier; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +class GeneratedStructureIndexTest { + @Test void nearestUsesHorizontalDistanceAndSurvivesSerialization() { + var id = Identifier.parse("ww_structures:ruins"); + var index = new GeneratedStructureIndex(); + index.record(id, new BlockPos(5, 200, 0)); + index.record(id, new BlockPos(10, 64, 0)); + index.record(Identifier.parse("ww_structures:other"), BlockPos.ZERO); + assertEquals(new BlockPos(5, 200, 0), index.nearest(id, new BlockPos(0, 64, 0)).orElseThrow()); + var json = GeneratedStructureIndex.CODEC.encodeStart(JsonOps.INSTANCE, index).getOrThrow(); + var restored = GeneratedStructureIndex.CODEC.parse(JsonOps.INSTANCE, json).getOrThrow(); + assertEquals(index.nearest(id, BlockPos.ZERO), restored.nearest(id, BlockPos.ZERO)); + assertTrue(restored.nearest(Identifier.parse("ww_structures:missing"), BlockPos.ZERO).isEmpty()); + restored.record(id, new BlockPos(5, 200, 0)); + assertFalse(restored.isDirty(), "Re-loading the same chunk must not dirty the index"); + } + + @Test void largeCoordinatesDoNotOverflow() { + assertEquals(3_600_000_000_000_000d, GeneratedStructureIndex.horizontalDistanceSquared( + new BlockPos(-30_000_000, 0, 0), new BlockPos(30_000_000, 0, 0))); + } +} diff --git a/src/datagen/java/org/polaris2023/wildwind/hfas/HFASMod.java b/src/datagen/java/org/polaris2023/wildwind/hfas/HFASMod.java new file mode 100644 index 0000000..7f89c5e --- /dev/null +++ b/src/datagen/java/org/polaris2023/wildwind/hfas/HFASMod.java @@ -0,0 +1,15 @@ +package org.polaris2023.wildwind.hfas; +import net.minecraft.resources.Identifier; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.fml.common.Mod; +/** Development-only datagen entry; never distributed to players. */ +@Mod(HFASMod.MOD_ID) +public final class HFASMod { + public static final String MOD_ID = "wild_wind_datagen"; + public HFASMod(IEventBus bus) {} + public static Identifier id(String path) { + String module = path.contains("tiny_cactus") ? "barren" : + java.util.stream.Stream.of("blaze", "soul", "scorched", "muddy_pig", "mudcrab", "piranha", "reach", "sink", "choke", "water_breathing").anyMatch(path::contains) ? "wilderness" : "core"; + return Identifier.fromNamespaceAndPath("wild_wind_" + module, path); + } +} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/datagen/HFASDatagen.java b/src/datagen/java/org/polaris2023/wildwind/hfas/datagen/HFASDatagen.java similarity index 100% rename from src/hfas/java/org/polaris2023/wildwind/hfas/datagen/HFASDatagen.java rename to src/datagen/java/org/polaris2023/wildwind/hfas/datagen/HFASDatagen.java diff --git a/src/datagen/java/org/polaris2023/wildwind/hfas/datagen/provider/ModDataMapsProvider.java b/src/datagen/java/org/polaris2023/wildwind/hfas/datagen/provider/ModDataMapsProvider.java new file mode 100644 index 0000000..fc8c1a5 --- /dev/null +++ b/src/datagen/java/org/polaris2023/wildwind/hfas/datagen/provider/ModDataMapsProvider.java @@ -0,0 +1,33 @@ +package org.polaris2023.wildwind.hfas.datagen.provider; + +import net.minecraft.core.HolderLookup; +import net.minecraft.data.PackOutput; +import net.neoforged.neoforge.common.data.DataMapProvider; +import net.neoforged.neoforge.registries.datamaps.builtin.NeoForgeDataMaps; +import net.neoforged.neoforge.registries.datamaps.builtin.Strippable; + +import java.util.concurrent.CompletableFuture; + +public class ModDataMapsProvider extends DataMapProvider { + /** + * Create a new provider. + * + * @param packOutput the output location + * @param lookupProvider a {@linkplain CompletableFuture} supplying the registries + */ + public ModDataMapsProvider(PackOutput packOutput, CompletableFuture lookupProvider) { + super(packOutput, lookupProvider); + } + + @Override + protected void gather(HolderLookup.Provider provider) { + builder(NeoForgeDataMaps.STRIPPABLES) + .add(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_LOG.getKey(), new Strippable(org.polaris2023.wildwind.core.block.ModBlocks.STRIPPED_AZALEA_LOG.get()), false) + .add(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_WOOD.getKey(), new Strippable(org.polaris2023.wildwind.core.block.ModBlocks.STRIPPED_AZALEA_WOOD.get()), false) + .add(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_LOG.getKey(), new Strippable(org.polaris2023.wildwind.wilderness.block.ModBlocks.STRIPPED_BLAZE_LOG.get()), false) + .add(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_WOOD.getKey(), new Strippable(org.polaris2023.wildwind.wilderness.block.ModBlocks.STRIPPED_BLAZE_WOOD.get()), false) + .add(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_LOG.getKey(), new Strippable(org.polaris2023.wildwind.wilderness.block.ModBlocks.STRIPPED_SOUL_LOG.get()), false) + .add(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_WOOD.getKey(), new Strippable(org.polaris2023.wildwind.wilderness.block.ModBlocks.STRIPPED_SOUL_WOOD.get()), false) + ; + } +} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/datagen/provider/ModDatapackProvider.java b/src/datagen/java/org/polaris2023/wildwind/hfas/datagen/provider/ModDatapackProvider.java similarity index 84% rename from src/hfas/java/org/polaris2023/wildwind/hfas/datagen/provider/ModDatapackProvider.java rename to src/datagen/java/org/polaris2023/wildwind/hfas/datagen/provider/ModDatapackProvider.java index 0c57964..d75e001 100644 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/datagen/provider/ModDatapackProvider.java +++ b/src/datagen/java/org/polaris2023/wildwind/hfas/datagen/provider/ModDatapackProvider.java @@ -7,8 +7,8 @@ import net.neoforged.neoforge.common.data.DatapackBuiltinEntriesProvider; import net.neoforged.neoforge.registries.NeoForgeRegistries; import org.polaris2023.wildwind.hfas.HFASMod; -import org.polaris2023.wildwind.hfas.entity.animal.MudcrabVariant; -import org.polaris2023.wildwind.hfas.registry.DatadrivenRegistryKey; +import org.polaris2023.wildwind.wilderness.entity.animal.MudcrabVariant; +import org.polaris2023.wildwind.wilderness.registry.DatadrivenRegistryKey; import org.polaris2023.wildwind.hfas.worldgen.ModBiomeModifiers; import org.polaris2023.wildwind.hfas.worldgen.ModConfiguredFeatures; import org.polaris2023.wildwind.hfas.worldgen.ModPlacedFeatures; @@ -23,6 +23,6 @@ public ModDatapackProvider(PackOutput output, CompletableFuture> getKnownEntityTypes() { return ModEntities.ENTITY_TYPES.getEntries() .stream() - .map(DeferredHolder::get); + .>map(DeferredHolder::get) + // Checked-in muddy_pig.json delegates to vanilla pig loot at runtime. + .filter(type -> type != ModEntities.MUDDY_PIG.get()); } @Override public void generate() { this.emptyLoot(ModEntities.MUDCRAB); + this.add( + ModEntities.PIRANHA.get(), + LootTable.lootTable() + .withPool( + LootPool.lootPool() + .setRolls(ConstantValue.exactly(1.0F)) + .add(LootItem.lootTableItem(org.polaris2023.wildwind.wilderness.registry.ModItems.PIRANHA.get()) + .apply(SmeltItemFunction.smelted().when(this.shouldSmeltLoot()))) + ) + .withPool( + LootPool.lootPool() + .setRolls(ConstantValue.exactly(1.0F)) + .add(LootItem.lootTableItem(Items.BONE_MEAL)) + .when(LootItemRandomChanceCondition.randomChance(0.05F)) + ) + .withPool( + LootPool.lootPool() + .setRolls(ConstantValue.exactly(1.0F)) + .add(LootItem.lootTableItem(org.polaris2023.wildwind.wilderness.registry.ModItems.FANG.get())) + .when(LootItemRandomChanceCondition.randomChance(0.05F)) + ) + ); } private void emptyLoot(DeferredHolder, EntityType> entityType) { diff --git a/src/datagen/java/org/polaris2023/wildwind/hfas/datagen/provider/ModModelProvider.java b/src/datagen/java/org/polaris2023/wildwind/hfas/datagen/provider/ModModelProvider.java new file mode 100644 index 0000000..35773e1 --- /dev/null +++ b/src/datagen/java/org/polaris2023/wildwind/hfas/datagen/provider/ModModelProvider.java @@ -0,0 +1,226 @@ +package org.polaris2023.wildwind.hfas.datagen.provider; + +import net.minecraft.client.data.models.model.ItemModelUtils; +import net.minecraft.resources.Identifier; +import org.polaris2023.wildwind.wilderness.registry.ModEntities; +import net.minecraft.client.data.models.model.ModelTemplates; +import net.minecraft.client.data.models.BlockModelGenerators; +import net.minecraft.client.data.models.ItemModelGenerators; +import net.minecraft.client.data.models.ModelProvider; +import net.minecraft.client.data.models.model.ModelLocationUtils; +import net.minecraft.client.data.models.model.ModelTemplate; +import net.minecraft.client.data.models.model.TexturedModel; +import net.minecraft.data.PackOutput; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.block.Block; +import org.polaris2023.wildwind.hfas.HFASMod; + +import java.util.function.Supplier; + +/** + * 模型生成器 + * 用于生成方块和物品的模型文件 + * + * @author baka4n + * @since 2026/04/15 + */ +public class ModModelProvider extends ModelProvider { + + public ModModelProvider(PackOutput output) { + super(output, HFASMod.MOD_ID); + } + + @Override + protected java.util.stream.Stream> getKnownBlocks() { + return net.minecraft.core.registries.BuiltInRegistries.BLOCK.listElements() + .filter(holder -> org.polaris2023.wildwind.core.api.WildWindModules.owns(holder.key().identifier().getNamespace())); + } + + @Override + protected java.util.stream.Stream> getKnownItems() { + return net.minecraft.core.registries.BuiltInRegistries.ITEM.listElements() + .filter(holder -> org.polaris2023.wildwind.core.api.WildWindModules.owns(holder.key().identifier().getNamespace())); + } + + @Override + protected void registerModels(BlockModelGenerators blockModels, ItemModelGenerators itemModels) { + itemModels.itemModelOutput.accept( + org.polaris2023.wildwind.wilderness.registry.ModItems.MUDDY_PIG_SPAWN_EGG.get(), + ItemModelUtils.plainModel( + Identifier.withDefaultNamespace("item/pig_spawn_egg"))); + org.polaris2023.wildwind.core.registry.ModItems.MATERIALS.forEach(item -> itemModels.generateFlatItem(item.get(), ModelTemplates.FLAT_ITEM)); + // ==================== 焚烬木套件 ==================== + registerWoodModels(blockModels, itemModels, + org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_LOG.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_WOOD.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.STRIPPED_BLAZE_LOG.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.STRIPPED_BLAZE_WOOD.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_PLANKS.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_STAIRS.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_SLAB.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_FENCE.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_FENCE_GATE.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_DOOR.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_TRAPDOOR.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_PRESSURE_PLATE.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_BUTTON.get() + ); + // 贴图已包含颜色;方块和物品均不叠加染色。 + createSimpleBlock(blockModels, org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_LEAVES.get()); + // 焚烬木树苗 + blockModels.createCrossBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_SAPLING.get(), BlockModelGenerators.PlantType.NOT_TINTED); + + // ==================== 灵焰木套件 ==================== + registerWoodModels(blockModels, itemModels, + org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_LOG.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_WOOD.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.STRIPPED_SOUL_LOG.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.STRIPPED_SOUL_WOOD.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_PLANKS.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_STAIRS.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_SLAB.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_FENCE.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_FENCE_GATE.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_DOOR.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_TRAPDOOR.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_PRESSURE_PLATE.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_BUTTON.get() + ); + // 与焚烬木树叶一致,保留贴图原色。 + createSimpleBlock(blockModels, org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_LEAVES.get()); + // 灵焰木树苗 + blockModels.createCrossBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_SAPLING.get(), BlockModelGenerators.PlantType.NOT_TINTED); + + // ==================== 杜鹃木套件 ==================== + registerWoodModels(blockModels, itemModels, + org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_LOG.get(), + org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_WOOD.get(), + org.polaris2023.wildwind.core.block.ModBlocks.STRIPPED_AZALEA_LOG.get(), + org.polaris2023.wildwind.core.block.ModBlocks.STRIPPED_AZALEA_WOOD.get(), + org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_PLANKS.get(), + org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_STAIRS.get(), + org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_SLAB.get(), + org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_FENCE.get(), + org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_FENCE_GATE.get(), + org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_DOOR.get(), + org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_TRAPDOOR.get(), + org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_PRESSURE_PLATE.get(), + org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_BUTTON.get() + ); + + blockModels.createShelf(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_SHELF.get(), org.polaris2023.wildwind.core.block.ModBlocks.STRIPPED_AZALEA_LOG.get()); + blockModels.blockStateOutput.accept(BlockModelGenerators.createSign(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_SIGN.get(), + signVariant("azalea_sign_rot_0"), signVariant("azalea_sign_rot_1"), signVariant("azalea_sign_rot_2"), signVariant("azalea_sign_rot_3"))); + blockModels.blockStateOutput.accept(BlockModelGenerators.createHangingSign(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_HANGING_SIGN.get(), + signVariant("azalea_hanging_sign_rot_0"), signVariant("azalea_hanging_sign_rot_1"), signVariant("azalea_hanging_sign_rot_2"), signVariant("azalea_hanging_sign_rot_3"), + signVariant("azalea_hanging_sign_attached_rot_0"), signVariant("azalea_hanging_sign_attached_rot_1"), signVariant("azalea_hanging_sign_attached_rot_2"), signVariant("azalea_hanging_sign_attached_rot_3"))); + blockModels.blockStateOutput.accept(net.minecraft.client.data.models.blockstates.MultiVariantGenerator.dispatch(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_WALL_SIGN.get(), signVariant("azalea_wall_sign")) + .with(BlockModelGenerators.ROTATION_HORIZONTAL_FACING_ALT)); + blockModels.blockStateOutput.accept(net.minecraft.client.data.models.blockstates.MultiVariantGenerator.dispatch(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_WALL_HANGING_SIGN.get(), signVariant("azalea_wall_hanging_sign")) + .with(BlockModelGenerators.ROTATION_HORIZONTAL_FACING_ALT)); + itemModels.generateFlatItem(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_SIGN.get().asItem(), ModelTemplates.FLAT_ITEM); + itemModels.generateFlatItem(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_HANGING_SIGN.get().asItem(), ModelTemplates.FLAT_ITEM); + itemModels.itemModelOutput.accept(org.polaris2023.wildwind.wilderness.registry.ModItems.TIPPED_ARROW.get(), ItemModelUtils.tintedModel( + Identifier.withDefaultNamespace("item/tipped_arrow"), new net.minecraft.client.color.item.Potion())); + // ==================== 其他方块 ==================== + // 焦灰草方块 - 使用简单的方块模型 + createSimpleBlock(blockModels, org.polaris2023.wildwind.wilderness.block.ModBlocks.SCORCHED_GRASS_BLOCK.get()); + + // 焦土 - 使用简单的方块模型 + createSimpleBlock(blockModels, org.polaris2023.wildwind.wilderness.block.ModBlocks.SCORCHED_DIRT.get()); + + // 焦灰草丛 - 使用交叉模型(类似草丛) + createCrossBlock(blockModels, org.polaris2023.wildwind.wilderness.block.ModBlocks.SCORCHED_GRASS.get()); + + // 焦灰枝条 - 使用交叉模型 + createCrossBlock(blockModels, org.polaris2023.wildwind.wilderness.block.ModBlocks.SCORCHED_TWIG.get()); + + // 仙人球 - 使用交叉模型 + createCrossBlock(blockModels, org.polaris2023.wildwind.barren.block.ModBlocks.TINY_CACTUS.get()); + + // 制箭台 - 使用简单方块模型 + blockModels.blockStateOutput.accept(net.minecraft.client.data.models.blockstates.MultiVariantGenerator.dispatch(org.polaris2023.wildwind.core.block.ModBlocks.KILN.get()) + .with(BlockModelGenerators.createBooleanModelDispatch(net.minecraft.world.level.block.state.properties.BlockStateProperties.LIT, + BlockModelGenerators.plainVariant(Identifier.withDefaultNamespace("block/furnace_on")), + BlockModelGenerators.plainVariant(Identifier.withDefaultNamespace("block/furnace")))) + .with(BlockModelGenerators.ROTATION_HORIZONTAL_FACING)); + itemModels.itemModelOutput.accept(org.polaris2023.wildwind.core.block.ModBlocks.KILN.get().asItem(), + ItemModelUtils.plainModel(Identifier.withDefaultNamespace("block/furnace"))); + + // ==================== 独立物品 ==================== + simpleItem(itemModels, org.polaris2023.wildwind.wilderness.registry.ModItems.CRAB_CLAW); + + // 万用蟹钳 - 使用手写 3D 模型(resources 下的 models/item/omni_claw.json),仅生成物品模型定义 + itemModels.itemModelOutput.accept( + org.polaris2023.wildwind.wilderness.registry.ModItems.OMNI_CLAW.get(), + ItemModelUtils.plainModel(ModelLocationUtils.getModelLocation(org.polaris2023.wildwind.wilderness.registry.ModItems.OMNI_CLAW.get())) + ); + simpleItem(itemModels, org.polaris2023.wildwind.wilderness.registry.ModItems.MUDCRAB_BUCKET); + simpleItem(itemModels, org.polaris2023.wildwind.wilderness.registry.ModItems.MUDCRAB_SPAWN_EGG); + + // ==================== 食人鱼 ==================== + registerPiranhaModels(itemModels); + } + + /** + * 注册木质方块模型 + */ + private void registerWoodModels(BlockModelGenerators blockModels, ItemModelGenerators itemModels, + Block log, Block wood, + Block strippedLog, Block strippedWood, + Block planks, Block stairs, Block slab, + Block fence, Block fenceGate, + Block door, Block trapdoor, + Block pressurePlate, Block button) { + // 原木 - 使用 WoodProvider(自动生成物品模型) + blockModels.woodProvider(log).logWithHorizontal(log).wood(wood); + + // 去皮原木(自动生成物品模型) + blockModels.woodProvider(strippedLog).logWithHorizontal(strippedLog).wood(strippedWood); + + // 使用 family 创建木质方块套件(包括木板,自动生成物品模型) + blockModels.family(planks) + .stairs(stairs) + .slab(slab) + .fence(fence) + .fenceGate(fenceGate) + .pressurePlate(pressurePlate) + .button(button); + + // 门(自动生成物品模型) + blockModels.createDoor(door); + + // 活板门(自动生成物品模型) + blockModels.createTrapdoor(trapdoor); + } + + /** + * 创建简单方块模型(六面相同贴图) + */ + private void createSimpleBlock(BlockModelGenerators blockModels, Block block) { + blockModels.createTrivialCube(block); + } + + /** + * 创建交叉模型(用于植物类方块) + */ + private void createCrossBlock(BlockModelGenerators blockModels, Block block) { + blockModels.createCrossBlock(block, BlockModelGenerators.PlantType.NOT_TINTED); + } + + private static net.minecraft.client.data.models.MultiVariant signVariant(String path) { + return BlockModelGenerators.plainVariant(HFASMod.id("block/" + path)); + } + + private void simpleItem(ItemModelGenerators itemModels, Supplier item){ + itemModels.generateFlatItem(item.get(), ModelTemplates.FLAT_ITEM); + } + + private void registerPiranhaModels(ItemModelGenerators itemModels) { + simpleItem(itemModels, org.polaris2023.wildwind.wilderness.registry.ModItems.PIRANHA); + simpleItem(itemModels, org.polaris2023.wildwind.wilderness.registry.ModItems.COOKED_PIRANHA); + simpleItem(itemModels, org.polaris2023.wildwind.wilderness.registry.ModItems.PIRANHA_BUCKET); + simpleItem(itemModels, org.polaris2023.wildwind.wilderness.registry.ModItems.PIRANHA_SPAWN_EGG); + simpleItem(itemModels, org.polaris2023.wildwind.wilderness.registry.ModItems.FANG); + } +} diff --git a/src/datagen/java/org/polaris2023/wildwind/hfas/datagen/provider/ModRecipeProvider.java b/src/datagen/java/org/polaris2023/wildwind/hfas/datagen/provider/ModRecipeProvider.java new file mode 100644 index 0000000..f3dbdf4 --- /dev/null +++ b/src/datagen/java/org/polaris2023/wildwind/hfas/datagen/provider/ModRecipeProvider.java @@ -0,0 +1,85 @@ +package org.polaris2023.wildwind.hfas.datagen.provider; + +import net.minecraft.core.HolderLookup; +import net.minecraft.data.PackOutput; +import net.minecraft.data.recipes.RecipeOutput; +import net.minecraft.data.recipes.ShapedRecipeBuilder; +import net.minecraft.data.recipes.SimpleCookingRecipeBuilder; +import net.minecraft.data.recipes.RecipeProvider; +import net.minecraft.data.recipes.RecipeCategory; +import net.minecraft.resources.ResourceKey; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.crafting.CookingBookCategory; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.Recipe; +import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; +import org.polaris2023.wildwind.hfas.HFASMod; + +import java.util.concurrent.CompletableFuture; + +/** + * 箭矢配方数据生成器 + * + * @author baka4n + * @since 2026/04/15 + */ +public class ModRecipeProvider extends RecipeProvider { + + + protected ModRecipeProvider(HolderLookup.Provider registries, RecipeOutput output) { + super(registries, output); + } + + @Override + protected void buildRecipes() { + ShapedRecipeBuilder.shaped(this.items, RecipeCategory.DECORATIONS, org.polaris2023.wildwind.core.block.ModBlocks.KILN.get()) + .define('B', Items.BRICK).define('F', Items.FURNACE).define('M', Items.PACKED_MUD) + .pattern(" B ").pattern("BFB").pattern("MMM") + .unlockedBy("has_furnace", this.has(Items.FURNACE)).save(this.output); + var planks = org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_PLANKS.get(); + var log = org.polaris2023.wildwind.core.block.ModBlocks.STRIPPED_AZALEA_LOG.get(); + ShapedRecipeBuilder.shaped(this.items, RecipeCategory.DECORATIONS, org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_SIGN.get(), 3) + .define('P', planks).define('S', Items.STICK).pattern("PPP").pattern("PPP").pattern(" S ") + .unlockedBy("has_azalea_planks", this.has(planks)).save(this.output); + ShapedRecipeBuilder.shaped(this.items, RecipeCategory.DECORATIONS, org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_HANGING_SIGN.get(), 6) + .define('L', log).define('C', Items.IRON_CHAIN).pattern("C C").pattern("LLL").pattern("LLL") + .unlockedBy("has_stripped_azalea_log", this.has(log)).save(this.output); + ShapedRecipeBuilder.shaped(this.items, RecipeCategory.DECORATIONS, org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_SHELF.get(), 6) + .define('L', log).pattern("LLL").pattern(" ").pattern("LLL") + .unlockedBy("has_stripped_azalea_log", this.has(log)).save(this.output); + // 生成所有箭矢组合配方 + // 生食人鱼 -> 熟食人鱼(熔炉) + SimpleCookingRecipeBuilder.smelting(Ingredient.of(org.polaris2023.wildwind.wilderness.registry.ModItems.PIRANHA.get()), RecipeCategory.FOOD, CookingBookCategory.FOOD, org.polaris2023.wildwind.wilderness.registry.ModItems.COOKED_PIRANHA.get(), 0.35F, 200) + .unlockedBy("has_" + org.polaris2023.wildwind.wilderness.registry.ModItems.PIRANHA.getId().getPath(), this.has(org.polaris2023.wildwind.wilderness.registry.ModItems.PIRANHA.get())) + .save(this.output); + // 万用蟹钳:铜锭x6 + 蟹钳x3 + ShapedRecipeBuilder.shaped(this.items, RecipeCategory.TOOLS, org.polaris2023.wildwind.wilderness.registry.ModItems.OMNI_CLAW.get()) + .define('I', Items.COPPER_INGOT) + .define('C', org.polaris2023.wildwind.wilderness.registry.ModItems.CRAB_CLAW.get()) + .pattern("ICC") + .pattern("IIC") + .pattern("III") + .unlockedBy("has_" + org.polaris2023.wildwind.wilderness.registry.ModItems.CRAB_CLAW.getId().getPath(), this.has(org.polaris2023.wildwind.wilderness.registry.ModItems.OMNI_CLAW.get())) + .save(this.output); + } + + + public static class Runner extends RecipeProvider.Runner { + + public Runner(PackOutput packOutput, CompletableFuture registries) { + super(packOutput, registries); + } + + @Override + protected RecipeProvider createRecipeProvider(HolderLookup.Provider provider, RecipeOutput recipeOutput) { + return new ModRecipeProvider(provider, recipeOutput); + } + + @Override + public String getName() { + return "Wild Wind " + HFASMod.MOD_ID + " Recipe Provider"; + } + } + + +} diff --git a/src/datagen/java/org/polaris2023/wildwind/hfas/datagen/provider/lang/EnUsLanguageProvider.java b/src/datagen/java/org/polaris2023/wildwind/hfas/datagen/provider/lang/EnUsLanguageProvider.java new file mode 100644 index 0000000..4deb9b2 --- /dev/null +++ b/src/datagen/java/org/polaris2023/wildwind/hfas/datagen/provider/lang/EnUsLanguageProvider.java @@ -0,0 +1,123 @@ +package org.polaris2023.wildwind.hfas.datagen.provider.lang; + +import net.minecraft.data.PackOutput; +import net.neoforged.neoforge.common.data.LanguageProvider; +import org.polaris2023.wildwind.hfas.HFASMod; + +/** + * 英语语言文件生成器 + * + * @author baka4n + * @since 2026/04/15 + */ +public class EnUsLanguageProvider extends LanguageProvider { + + public EnUsLanguageProvider(PackOutput output) { + super(output, HFASMod.MOD_ID, "en_us"); + } + + @Override + protected void addTranslations() { + add("effect.wild_wind_wilderness.sink", "Sink"); + add("effect.wild_wind_wilderness.choke", "Choke"); + add("enchantment.wild_wind_core.melting", "Melting"); + add("item.wild_wind_core.duckweed", "Duckweed"); + add("item.wild_wind_core.calamari", "Calamari"); + add("item.wild_wind_core.cooked_calamari", "Cooked Calamari"); + add("item.wild_wind_core.cooked_egg", "Fried Egg"); + add("item.wild_wind_core.baked_seeds", "Baked Seeds"); + add("item.wild_wind_core.cooked_frog_legs", "Cooked Frog Legs"); + add("item.wild_wind_core.frog_legs", "Raw Frog Legs"); + add("entity.wild_wind_wilderness.muddy_pig", "Muddy Pig"); + add("item.wild_wind_wilderness.muddy_pig_spawn_egg", "Muddy Pig Spawn Egg"); + // 焚烬木套件 + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_LOG, "Blaze Log"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_WOOD, "Blaze Wood"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.STRIPPED_BLAZE_LOG, "Stripped Blaze Log"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.STRIPPED_BLAZE_WOOD, "Stripped Blaze Wood"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_PLANKS, "Blaze Planks"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_STAIRS, "Blaze Stairs"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_SLAB, "Blaze Slab"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_FENCE, "Blaze Fence"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_FENCE_GATE, "Blaze Fence Gate"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_DOOR, "Blaze Door"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_TRAPDOOR, "Blaze Trapdoor"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_PRESSURE_PLATE, "Blaze Pressure Plate"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_BUTTON, "Blaze Button"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_LEAVES, "Blaze Leaves"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_SAPLING, "Blaze Sapling"); + + // 灵焰木套件 + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_LOG, "Soul Log"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_WOOD, "Soul Wood"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.STRIPPED_SOUL_LOG, "Stripped Soul Log"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.STRIPPED_SOUL_WOOD, "Stripped Soul Wood"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_PLANKS, "Soul Planks"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_STAIRS, "Soul Stairs"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_SLAB, "Soul Slab"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_FENCE, "Soul Fence"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_FENCE_GATE, "Soul Fence Gate"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_DOOR, "Soul Door"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_TRAPDOOR, "Soul Trapdoor"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_PRESSURE_PLATE, "Soul Pressure Plate"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_BUTTON, "Soul Button"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_LEAVES, "Soul Leaves"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_SAPLING, "Soul Sapling"); + + // 杜鹃木套件 + addBlock(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_LOG, "Azalea Log"); + addBlock(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_WOOD, "Azalea Wood"); + addBlock(org.polaris2023.wildwind.core.block.ModBlocks.STRIPPED_AZALEA_LOG, "Stripped Azalea Log"); + addBlock(org.polaris2023.wildwind.core.block.ModBlocks.STRIPPED_AZALEA_WOOD, "Stripped Azalea Wood"); + addBlock(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_PLANKS, "Azalea Planks"); + addBlock(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_STAIRS, "Azalea Stairs"); + addBlock(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_SLAB, "Azalea Slab"); + addBlock(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_FENCE, "Azalea Fence"); + addBlock(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_FENCE_GATE, "Azalea Fence Gate"); + addBlock(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_DOOR, "Azalea Door"); + addBlock(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_TRAPDOOR, "Azalea Trapdoor"); + addBlock(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_PRESSURE_PLATE, "Azalea Pressure Plate"); + addBlock(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_BUTTON, "Azalea Button"); + + // 其他方块 + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.SCORCHED_GRASS_BLOCK, "Scorched Grass Block"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.SCORCHED_DIRT, "Scorched Dirt"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.SCORCHED_GRASS, "Scorched Grass"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.SCORCHED_TWIG, "Scorched Twig"); + addBlock(org.polaris2023.wildwind.barren.block.ModBlocks.TINY_CACTUS, "Tiny Cactus"); + addBlock(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_SIGN, "Azalea Sign"); + addBlock(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_WALL_SIGN, "Azalea Wall Sign"); + addBlock(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_HANGING_SIGN, "Azalea Hanging Sign"); + addBlock(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_WALL_HANGING_SIGN, "Azalea Wall Hanging Sign"); + addBlock(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_SHELF, "Azalea Shelf"); + add("item.wild_wind_wilderness.tipped_arrow", "Arrow of Reach"); + add("item.wild_wind_wilderness.tipped_arrow.effect.reach", "Arrow of Reach"); + add("item.wild_wind_wilderness.tipped_arrow.effect.long_reach", "Arrow of Reach"); + add("entity.wild_wind_wilderness.arrow", "Arrow of Reach"); + addBlock(org.polaris2023.wildwind.core.block.ModBlocks.KILN, "Kiln"); + + // GUI + // 属性 + add("attributes.wild_wind_wilderness.extra_item_pickup_range", "Extra Item Pickup Range"); + + // Reach effect & potions + add("effect.wild_wind_wilderness.reach", "Reach"); + add("item.minecraft.potion.effect.reach", "Potion of Reach"); + add("item.minecraft.splash_potion.effect.reach", "Splash Potion of Reach"); + add("item.minecraft.lingering_potion.effect.reach", "Lingering Potion of Reach"); + add("item.minecraft.tipped_arrow.effect.reach", "Arrow of Reach"); + add("item.minecraft.potion.effect.long_reach", "Potion of Reach"); + add("item.minecraft.splash_potion.effect.long_reach", "Splash Potion of Reach"); + add("item.minecraft.lingering_potion.effect.long_reach", "Lingering Potion of Reach"); + add("item.minecraft.tipped_arrow.effect.long_reach", "Arrow of Reach"); + + // Direfish sound subtitles + add("subtitles.entity.piranha.attack", "Direfish attacks"); + add("subtitles.entity.piranha.death", "Direfish dies"); + + //创造模式物品栏 + add("mod.wild_wind.name", "Wild Wind"); + + ZhEnCombineLangProvider.addLang(this, "en_us"); + } +} diff --git a/src/datagen/java/org/polaris2023/wildwind/hfas/datagen/provider/lang/ZhCnLanguageProvider.java b/src/datagen/java/org/polaris2023/wildwind/hfas/datagen/provider/lang/ZhCnLanguageProvider.java new file mode 100644 index 0000000..144fff6 --- /dev/null +++ b/src/datagen/java/org/polaris2023/wildwind/hfas/datagen/provider/lang/ZhCnLanguageProvider.java @@ -0,0 +1,126 @@ +package org.polaris2023.wildwind.hfas.datagen.provider.lang; + +import net.minecraft.data.PackOutput; +import net.neoforged.neoforge.common.data.LanguageProvider; +import org.polaris2023.wildwind.hfas.HFASMod; + +/** + * 中文语言文件生成器 + * + * @author baka4n + * @since 2026/04/15 + */ +public class ZhCnLanguageProvider extends LanguageProvider { + + public ZhCnLanguageProvider(PackOutput output) { + super(output, HFASMod.MOD_ID, "zh_cn"); + } + + @Override + protected void addTranslations() { + add("effect.wild_wind_wilderness.sink", "沉溺"); + add("effect.wild_wind_wilderness.choke", "窒息"); + add("enchantment.wild_wind_core.melting", "熔炼"); + add("item.wild_wind_core.duckweed", "浮萍"); + add("item.wild_wind_core.calamari", "鱿鱼须"); + add("item.wild_wind_core.cooked_calamari", "熟鱿鱼须"); + add("item.wild_wind_core.cooked_egg", "煎蛋"); + add("item.wild_wind_core.baked_seeds", "烤种子"); + add("item.wild_wind_core.cooked_frog_legs", "熟蛙腿"); + add("item.wild_wind_core.frog_legs", "生蛙腿"); + add("entity.wild_wind_wilderness.muddy_pig", "泥猪"); + add("item.wild_wind_wilderness.muddy_pig_spawn_egg", "泥猪刷怪蛋"); + // 焚烬木套件 + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_LOG, "焚烬木原木"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_WOOD, "焚烬木"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.STRIPPED_BLAZE_LOG, "去皮焚烬木原木"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.STRIPPED_BLAZE_WOOD, "去皮焚烬木"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_PLANKS, "焚烬木木板"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_STAIRS, "焚烬木楼梯"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_SLAB, "焚烬木台阶"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_FENCE, "焚烬木栅栏"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_FENCE_GATE, "焚烬木栅栏门"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_DOOR, "焚烬木门"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_TRAPDOOR, "焚烬木活板门"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_PRESSURE_PLATE, "焚烬木压力板"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_BUTTON, "焚烬木按钮"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_LEAVES, "焚烬木树叶"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_SAPLING, "焚烬木树苗"); + + // 灵焰木套件 + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_LOG, "灵焰木原木"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_WOOD, "灵焰木"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.STRIPPED_SOUL_LOG, "去皮灵焰木原木"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.STRIPPED_SOUL_WOOD, "去皮灵焰木"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_PLANKS, "灵焰木木板"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_STAIRS, "灵焰木楼梯"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_SLAB, "灵焰木台阶"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_FENCE, "灵焰木栅栏"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_FENCE_GATE, "灵焰木栅栏门"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_DOOR, "灵焰木门"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_TRAPDOOR, "灵焰木活板门"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_PRESSURE_PLATE, "灵焰木压力板"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_BUTTON, "灵焰木按钮"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_LEAVES, "灵焰木树叶"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_SAPLING, "灵焰木树苗"); + + // 杜鹃木套件 + addBlock(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_LOG, "杜鹃木原木"); + addBlock(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_WOOD, "杜鹃木"); + addBlock(org.polaris2023.wildwind.core.block.ModBlocks.STRIPPED_AZALEA_LOG, "去皮杜鹃木原木"); + addBlock(org.polaris2023.wildwind.core.block.ModBlocks.STRIPPED_AZALEA_WOOD, "去皮杜鹃木"); + addBlock(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_PLANKS, "杜鹃木木板"); + addBlock(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_STAIRS, "杜鹃木楼梯"); + addBlock(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_SLAB, "杜鹃木台阶"); + addBlock(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_FENCE, "杜鹃木栅栏"); + addBlock(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_FENCE_GATE, "杜鹃木栅栏门"); + addBlock(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_DOOR, "杜鹃木门"); + addBlock(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_TRAPDOOR, "杜鹃木活板门"); + addBlock(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_PRESSURE_PLATE, "杜鹃木压力板"); + addBlock(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_BUTTON, "杜鹃木按钮"); + + // 其他方块 + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.SCORCHED_GRASS_BLOCK, "焦灰草方块"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.SCORCHED_DIRT, "焦土"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.SCORCHED_GRASS, "焦灰草丛"); + addBlock(org.polaris2023.wildwind.wilderness.block.ModBlocks.SCORCHED_TWIG, "焦灰枝条"); + addBlock(org.polaris2023.wildwind.barren.block.ModBlocks.TINY_CACTUS, "仙人球"); + addBlock(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_SIGN, "杜鹃木告示牌"); + addBlock(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_WALL_SIGN, "墙上的杜鹃木告示牌"); + addBlock(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_HANGING_SIGN, "悬挂式杜鹃木告示牌"); + addBlock(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_WALL_HANGING_SIGN, "墙上的悬挂式杜鹃木告示牌"); + addBlock(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_SHELF, "杜鹃木展示架"); + add("item.wild_wind_wilderness.tipped_arrow", "延展之箭"); + add("item.wild_wind_wilderness.tipped_arrow.effect.reach", "延展之箭"); + add("item.wild_wind_wilderness.tipped_arrow.effect.long_reach", "延展之箭"); + add("entity.wild_wind_wilderness.arrow", "延展之箭"); + addBlock(org.polaris2023.wildwind.core.block.ModBlocks.KILN, "窑炉"); + + // GUI + // 属性 + add("attributes.wild_wind_wilderness.extra_item_pickup_range", "额外物品拾取距离"); + + // 延展(reach)效果与药水 + add("effect.wild_wind_wilderness.reach", "延展"); + add("item.minecraft.potion.effect.reach", "延展药水"); + add("item.minecraft.splash_potion.effect.reach", "喷溅型延展药水"); + add("item.minecraft.lingering_potion.effect.reach", "滞留型延展药水"); + add("item.minecraft.tipped_arrow.effect.reach", "延展之箭"); + add("item.minecraft.potion.effect.long_reach", "延展药水"); + add("item.minecraft.splash_potion.effect.long_reach", "喷溅型延展药水"); + add("item.minecraft.lingering_potion.effect.long_reach", "滞留型延展药水"); + add("item.minecraft.tipped_arrow.effect.long_reach", "延展之箭"); + + // 恐鱼音效字幕 + add("subtitles.entity.piranha.attack", "恐鱼袭击"); + add("subtitles.entity.piranha.death", "恐鱼死亡"); + + //创造模式物品栏 + add("mod.wild_wind.name", "原野之风"); + + ZhEnCombineLangProvider.addLang(this, "zh_cn"); + + } + + +} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/datagen/provider/lang/ZhEnCombineLangProvider.java b/src/datagen/java/org/polaris2023/wildwind/hfas/datagen/provider/lang/ZhEnCombineLangProvider.java similarity index 65% rename from src/hfas/java/org/polaris2023/wildwind/hfas/datagen/provider/lang/ZhEnCombineLangProvider.java rename to src/datagen/java/org/polaris2023/wildwind/hfas/datagen/provider/lang/ZhEnCombineLangProvider.java index 1520ede..904e6f9 100644 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/datagen/provider/lang/ZhEnCombineLangProvider.java +++ b/src/datagen/java/org/polaris2023/wildwind/hfas/datagen/provider/lang/ZhEnCombineLangProvider.java @@ -4,8 +4,7 @@ import net.minecraft.world.item.Item; import net.minecraft.world.level.block.Block; import net.neoforged.neoforge.common.data.LanguageProvider; -import org.polaris2023.wildwind.hfas.registry.ModEntities; -import org.polaris2023.wildwind.hfas.registry.ModItems; +import org.polaris2023.wildwind.wilderness.registry.ModEntities; import java.util.HashMap; import java.util.Map; @@ -36,10 +35,15 @@ public static void addLang(LanguageProvider provider, String lang){ private static void addItems() { - addItem(ModItems.MUDCRAB_SPAWN_EGG, "Mudcrab Spawn Egg", "泥沼蟹刷怪蛋"); - addItem(ModItems.MUDCRAB_BUCKET, "Bucket of Mudcrab", "泥沼蟹桶"); - addItem(ModItems.CRAB_CLAW, "Crab Claw", "蟹钳"); - addItem(ModItems.OMNI_CLAW, "Omni Craw", "万用蟹钳"); + addItem(org.polaris2023.wildwind.wilderness.registry.ModItems.MUDCRAB_SPAWN_EGG, "Mudcrab Spawn Egg", "泥沼蟹刷怪蛋"); + addItem(org.polaris2023.wildwind.wilderness.registry.ModItems.MUDCRAB_BUCKET, "Bucket of Mudcrab", "泥沼蟹桶"); + addItem(org.polaris2023.wildwind.wilderness.registry.ModItems.CRAB_CLAW, "Crab Claw", "蟹钳"); + addItem(org.polaris2023.wildwind.wilderness.registry.ModItems.OMNI_CLAW, "Omni Craw", "万用蟹钳"); + addItem(org.polaris2023.wildwind.wilderness.registry.ModItems.PIRANHA_SPAWN_EGG, "Direfish Spawn Egg", "恐鱼刷怪蛋"); + addItem(org.polaris2023.wildwind.wilderness.registry.ModItems.PIRANHA, "Raw Direfish", "生恐鱼"); + addItem(org.polaris2023.wildwind.wilderness.registry.ModItems.COOKED_PIRANHA, "Cooked Direfish", "熟恐鱼"); + addItem(org.polaris2023.wildwind.wilderness.registry.ModItems.FANG, "Fang", "尖牙"); + addItem(org.polaris2023.wildwind.wilderness.registry.ModItems.PIRANHA_BUCKET, "Bucket of Direfish", "恐鱼桶"); } private static void addBlocks() { @@ -47,6 +51,7 @@ private static void addBlocks() { private static void addEntities() { addEntity(ModEntities.MUDCRAB, "Mudcrab", "泥沼蟹"); + addEntity(ModEntities.PIRANHA, "Direfish", "恐鱼"); } private static void addItem(Supplier s, String en, String zh){ diff --git a/src/datagen/java/org/polaris2023/wildwind/hfas/datagen/provider/loot/BlockLoot.java b/src/datagen/java/org/polaris2023/wildwind/hfas/datagen/provider/loot/BlockLoot.java new file mode 100644 index 0000000..dbc1692 --- /dev/null +++ b/src/datagen/java/org/polaris2023/wildwind/hfas/datagen/provider/loot/BlockLoot.java @@ -0,0 +1,89 @@ +package org.polaris2023.wildwind.hfas.datagen.provider.loot; + +import net.minecraft.core.HolderLookup; +import net.minecraft.data.loot.BlockLootSubProvider; +import net.minecraft.world.flag.FeatureFlags; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.block.Block; +import org.jspecify.annotations.NonNull; + +import java.util.Set; + +public class BlockLoot extends BlockLootSubProvider { + public BlockLoot(HolderLookup.Provider registries) { + super(Set.of(), FeatureFlags.DEFAULT_FLAGS, registries); + } + + @Override + protected @NonNull Iterable getKnownBlocks() { + return java.util.stream.Stream.of(org.polaris2023.wildwind.core.block.ModBlocks.BLOCKS,org.polaris2023.wildwind.wilderness.block.ModBlocks.BLOCKS,org.polaris2023.wildwind.barren.block.ModBlocks.BLOCKS).flatMap(reg -> reg.getEntries().stream()).map(h -> (Block) h.value()).toList(); + } + + @Override + protected void generate() { + // 焚烬木套件 + dropSelf(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_LOG.get()); + dropSelf(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_WOOD.get()); + dropSelf(org.polaris2023.wildwind.wilderness.block.ModBlocks.STRIPPED_BLAZE_LOG.get()); + dropSelf(org.polaris2023.wildwind.wilderness.block.ModBlocks.STRIPPED_BLAZE_WOOD.get()); + dropSelf(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_PLANKS.get()); + dropSelf(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_STAIRS.get()); + dropSelf(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_SLAB.get()); + dropSelf(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_FENCE.get()); + dropSelf(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_FENCE_GATE.get()); + dropSelf(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_PRESSURE_PLATE.get()); + dropSelf(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_BUTTON.get()); + // 树叶 - 使用树叶掉落逻辑 + add(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_LEAVES.get(), createLeavesDrops(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_LEAVES.get(), org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_SAPLING.get(), 0.05F)); + dropSelf(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_SAPLING.get()); + // 门需要特殊处理 + add(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_DOOR.get(), createDoorTable(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_DOOR.get())); + dropSelf(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_TRAPDOOR.get()); + + // 灵焰木套件 + dropSelf(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_LOG.get()); + dropSelf(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_WOOD.get()); + dropSelf(org.polaris2023.wildwind.wilderness.block.ModBlocks.STRIPPED_SOUL_LOG.get()); + dropSelf(org.polaris2023.wildwind.wilderness.block.ModBlocks.STRIPPED_SOUL_WOOD.get()); + dropSelf(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_PLANKS.get()); + dropSelf(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_STAIRS.get()); + dropSelf(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_SLAB.get()); + dropSelf(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_FENCE.get()); + dropSelf(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_FENCE_GATE.get()); + dropSelf(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_PRESSURE_PLATE.get()); + dropSelf(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_BUTTON.get()); + // 树叶 - 使用树叶掉落逻辑 + add(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_LEAVES.get(), createLeavesDrops(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_LEAVES.get(), org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_SAPLING.get(), 0.05F)); + dropSelf(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_SAPLING.get()); + // 门需要特殊处理 + add(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_DOOR.get(), createDoorTable(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_DOOR.get())); + dropSelf(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_TRAPDOOR.get()); + + dropSelf(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_SIGN.get()); + dropSelf(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_HANGING_SIGN.get()); + dropSelf(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_SHELF.get()); + // 杜鹃木套件 + dropSelf(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_LOG.get()); + dropSelf(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_WOOD.get()); + dropSelf(org.polaris2023.wildwind.core.block.ModBlocks.STRIPPED_AZALEA_LOG.get()); + dropSelf(org.polaris2023.wildwind.core.block.ModBlocks.STRIPPED_AZALEA_WOOD.get()); + dropSelf(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_PLANKS.get()); + dropSelf(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_STAIRS.get()); + dropSelf(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_SLAB.get()); + dropSelf(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_FENCE.get()); + dropSelf(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_FENCE_GATE.get()); + dropSelf(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_PRESSURE_PLATE.get()); + dropSelf(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_BUTTON.get()); + // 门需要特殊处理 + add(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_DOOR.get(), createDoorTable(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_DOOR.get())); + dropSelf(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_TRAPDOOR.get()); + + // 其他方块 + dropSelf(org.polaris2023.wildwind.wilderness.block.ModBlocks.SCORCHED_GRASS_BLOCK.get()); + dropSelf(org.polaris2023.wildwind.wilderness.block.ModBlocks.SCORCHED_DIRT.get()); + dropSelf(org.polaris2023.wildwind.wilderness.block.ModBlocks.SCORCHED_GRASS.get()); + dropSelf(org.polaris2023.wildwind.wilderness.block.ModBlocks.SCORCHED_TWIG.get()); + dropSelf(org.polaris2023.wildwind.barren.block.ModBlocks.TINY_CACTUS.get()); + add(org.polaris2023.wildwind.core.block.ModBlocks.KILN.get(), createNameableBlockEntityTable(org.polaris2023.wildwind.core.block.ModBlocks.KILN.get())); + } +} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/datagen/provider/tag/ModBiomeTagsProvider.java b/src/datagen/java/org/polaris2023/wildwind/hfas/datagen/provider/tag/ModBiomeTagsProvider.java similarity index 90% rename from src/hfas/java/org/polaris2023/wildwind/hfas/datagen/provider/tag/ModBiomeTagsProvider.java rename to src/datagen/java/org/polaris2023/wildwind/hfas/datagen/provider/tag/ModBiomeTagsProvider.java index 20f33fb..0ed4533 100644 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/datagen/provider/tag/ModBiomeTagsProvider.java +++ b/src/datagen/java/org/polaris2023/wildwind/hfas/datagen/provider/tag/ModBiomeTagsProvider.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.biome.Biomes; import net.neoforged.neoforge.common.Tags; import org.polaris2023.wildwind.hfas.HFASMod; -import org.polaris2023.wildwind.hfas.tag.ModBiomeTags; +import org.polaris2023.wildwind.wilderness.tag.ModBiomeTags; import javax.annotation.Nullable; import java.util.concurrent.CompletableFuture; @@ -47,5 +47,8 @@ protected void addTags(HolderLookup.Provider provider) { .add(Biomes.SNOWY_TAIGA) .add(Biomes.SNOWY_BEACH) .addTag(BiomeTags.IS_END); + tag(ModBiomeTags.EntityGen.PIRANHA_SPAWNS) + .add(Biomes.JUNGLE) + .addTag(Tags.Biomes.IS_SWAMP); } } diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/datagen/provider/tag/ModBlockTagsProvider.java b/src/datagen/java/org/polaris2023/wildwind/hfas/datagen/provider/tag/ModBlockTagsProvider.java similarity index 51% rename from src/hfas/java/org/polaris2023/wildwind/hfas/datagen/provider/tag/ModBlockTagsProvider.java rename to src/datagen/java/org/polaris2023/wildwind/hfas/datagen/provider/tag/ModBlockTagsProvider.java index 84c03cb..73012da 100644 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/datagen/provider/tag/ModBlockTagsProvider.java +++ b/src/datagen/java/org/polaris2023/wildwind/hfas/datagen/provider/tag/ModBlockTagsProvider.java @@ -12,8 +12,7 @@ import net.neoforged.neoforge.common.Tags; import net.neoforged.neoforge.common.data.BlockTagsProvider; import org.polaris2023.wildwind.hfas.HFASMod; -import org.polaris2023.wildwind.hfas.block.ModBlocks; -import org.polaris2023.wildwind.hfas.tag.ModBlockTags; +import org.polaris2023.wildwind.wilderness.tag.ModBlockTags; import java.util.Arrays; import java.util.concurrent.CompletableFuture; @@ -36,69 +35,75 @@ public ModBlockTagsProvider(PackOutput output, CompletableFuture + * 迁移至26.2时旧有的IntrinsicHolderTagsProvider已被移除。改为父类TagsProvider并由addToTag方法桥接。 + * TODO_FINISHED: 部分item tag key存在缺失问题,已模仿原版行为进行处理,但无法确定这种缺失是否系系统性删除,无法确保对应功能一定可以正常工作。请求测试阶段重点检查。 + * 见[Need Check]注释部分。 + * ——landis, 2026/9/1 + * + * @author baka4n + * @since 2026/04/15 + */ +public class ModItemTagsProvider extends TagsProvider { + + public ModItemTagsProvider(PackOutput output, CompletableFuture lookupProvider) { +// super(output, Registries.ITEM, lookupProvider, item -> item.builtInRegistryHolder().key(), HFASMod.MOD_ID); + super(output, Registries.ITEM, lookupProvider, HFASMod.MOD_ID); + } + + @Override + protected void addTags(HolderLookup.Provider provider) { + addToTag(ItemTags.ARROWS, org.polaris2023.wildwind.wilderness.registry.ModItems.TIPPED_ARROW.get()); + addToTag(TagKey.create(Registries.ITEM, Identifier.withDefaultNamespace("signs")), org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_SIGN.get().asItem()); + addToTag(TagKey.create(Registries.ITEM, Identifier.withDefaultNamespace("hanging_signs")), org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_HANGING_SIGN.get().asItem()); + addToTag(TagKey.create(Registries.ITEM, Identifier.withDefaultNamespace("wooden_shelves")), org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_SHELF.get().asItem()); + registerWoodLogItemTag("blaze", + org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_LOG.get(), org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_WOOD.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.STRIPPED_BLAZE_LOG.get(), org.polaris2023.wildwind.wilderness.block.ModBlocks.STRIPPED_BLAZE_WOOD.get()); + registerWoodLogItemTag("soul", + org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_LOG.get(), org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_WOOD.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.STRIPPED_SOUL_LOG.get(), org.polaris2023.wildwind.wilderness.block.ModBlocks.STRIPPED_SOUL_WOOD.get()); + registerWoodLogItemTag("azalea", + org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_LOG.get(), org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_WOOD.get(), + org.polaris2023.wildwind.core.block.ModBlocks.STRIPPED_AZALEA_LOG.get(), org.polaris2023.wildwind.core.block.ModBlocks.STRIPPED_AZALEA_WOOD.get()); + + // ==================== 焚烬木物品标签 ==================== + registerWoodItemTags( + org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_LOG.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_WOOD.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.STRIPPED_BLAZE_LOG.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.STRIPPED_BLAZE_WOOD.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_PLANKS.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_STAIRS.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_SLAB.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_FENCE.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_FENCE_GATE.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_DOOR.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_TRAPDOOR.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_PRESSURE_PLATE.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_BUTTON.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_LEAVES.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_SAPLING.get() + ); + + // ==================== 灵焰木物品标签 ==================== + registerWoodItemTags( + org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_LOG.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_WOOD.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.STRIPPED_SOUL_LOG.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.STRIPPED_SOUL_WOOD.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_PLANKS.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_STAIRS.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_SLAB.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_FENCE.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_FENCE_GATE.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_DOOR.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_TRAPDOOR.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_PRESSURE_PLATE.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_BUTTON.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_LEAVES.get(), + org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_SAPLING.get() + ); + + // ==================== 杜鹃木物品标签 ==================== + registerWoodItemTags( + org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_LOG.get(), + org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_WOOD.get(), + org.polaris2023.wildwind.core.block.ModBlocks.STRIPPED_AZALEA_LOG.get(), + org.polaris2023.wildwind.core.block.ModBlocks.STRIPPED_AZALEA_WOOD.get(), + org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_PLANKS.get(), + org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_STAIRS.get(), + org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_SLAB.get(), + org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_FENCE.get(), + org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_FENCE_GATE.get(), + org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_DOOR.get(), + org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_TRAPDOOR.get(), + org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_PRESSURE_PLATE.get(), + org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_BUTTON.get(), + null, // 杜鹃木使用原版树叶 + null // 杜鹃木使用原版树苗 + ); + + tag(Tags.Items.ANIMAL_FOODS) + .addTag(ModItemTags.MUDCRAB_FOOD); + addToTag(ModItemTags.MUDCRAB_FOOD, Items.SPIDER_EYE); + + // ==================== 食人鱼相关物品标签 ==================== + // 猫、豹猫以生食人鱼为食 + addToTag(ItemTags.CAT_FOOD, org.polaris2023.wildwind.wilderness.registry.ModItems.PIRANHA.get()); + addToTag(ItemTags.OCELOT_FOOD, org.polaris2023.wildwind.wilderness.registry.ModItems.PIRANHA.get()); + // 狼以生/熟食人鱼为食 + addToTag(ItemTags.WOLF_FOOD, org.polaris2023.wildwind.wilderness.registry.ModItems.PIRANHA.get(), org.polaris2023.wildwind.wilderness.registry.ModItems.COOKED_PIRANHA.get()); + // 原版鱼类标签 + addToTag(ItemTags.FISHES, org.polaris2023.wildwind.wilderness.registry.ModItems.PIRANHA.get(), org.polaris2023.wildwind.wilderness.registry.ModItems.COOKED_PIRANHA.get()); + // 熟鱼食物标签 + addToTag(Tags.Items.FOODS_COOKED_FISH, org.polaris2023.wildwind.wilderness.registry.ModItems.COOKED_PIRANHA.get()); + } + + /** + * 注册木质物品标签 + */ + private void registerWoodItemTags( + Block log, Block wood, + Block strippedLog, Block strippedWood, + Block planks, Block stairs, Block slab, + Block fence, Block fenceGate, + Block door, Block trapdoor, + Block pressurePlate, Block button, + Block leaves, Block sapling) { + + // 原木物品标签 + addToTag(ItemTags.LOGS, log, wood, strippedLog, strippedWood); + addToTag(ItemTags.LOGS_THAT_BURN, log, wood, strippedLog, strippedWood); + addToTag(Tags.Items.STRIPPED_LOGS, strippedLog); + addToTag(Tags.Items.STRIPPED_WOODS, strippedWood); +// tag(ItemTags.LOGS) +// .add(log.asItem()) +// .add(wood.asItem()) +// .add(strippedLog.asItem()) +// .add(strippedWood.asItem()); + + // 木板物品标签 + addToTag(ItemTags.PLANKS, planks); + + // 木质楼梯物品标签 + addToTag(ItemTags.WOODEN_STAIRS,stairs); + + // 木质台阶物品标签 + addToTag(ItemTags.WOODEN_SLABS, slab); + + // 木质栅栏物品标签 + addToTag(ItemTags.WOODEN_FENCES, fence); + addToTag(Tags.Items.FENCES_WOODEN, fence); + + // 栅栏物品标签 + // 栅栏tag默认包含"#c:fences/wooden",弃用 +// tag(Tags.Items.FENCES) +// .add(fence.asItem()); + + // 木质栅栏门物品标签 + addToTag(Tags.Items.FENCE_GATES_WOODEN, fenceGate); + + // 栅栏门物品标签 + addToTag(ItemTags.FENCE_GATES, fenceGate); + + // 木质门物品标签 + addToTag(ItemTags.WOODEN_DOORS,door); + + // 门物品标签 + // bugjump不知道给这玩意更新到哪去了 item没key 难绷 + // [NeedCheck] + addToTag(BlockItemTags.DOORS.item(), door); + + // 活板门物品标签 + // 续上:我要点名某些明明有包含关系但是就是不引用子tag还要把key删掉的tag + // [NeedCheck] + addToTag(BlockItemTags.TRAPDOORS.item(), trapdoor); + + // 木质活板门物品标签 + addToTag(ItemTags.WOODEN_TRAPDOORS, trapdoor); + + // 木质压力板物品标签 + addToTag(ItemTags.WOODEN_PRESSURE_PLATES, pressurePlate); + + // 木质按钮物品标签 + addToTag(ItemTags.WOODEN_BUTTONS, button); + + // 按钮物品标签 + // 不是哥们 你怎么也没了我朝为 + // [NeedCheck] + addToTag(BlockItemTags.BUTTONS.item(), button); + + // 树叶物品标签 + if (leaves != null) { + addToTag(ItemTags.LEAVES, leaves); + } + + // 树苗物品标签 + if (sapling != null) { + addToTag(ItemTags.SAPLINGS, sapling); + } + } + + private void registerWoodLogItemTag(String name, Block log, Block wood, Block strippedLog, Block strippedWood) { + TagKey logsTag = TagKey.create( + Registries.ITEM, + HFASMod.id(name + "_logs") + ); + addToTag(logsTag, log, wood, strippedLog, strippedWood); + } + + @SuppressWarnings("all") + public void addToTag(TagKey tag, Block... items){ + if(items.length == 0) return; + tag(tag).addAll(Arrays.stream(items).map(Block::asItem).map(Item::builtInRegistryHolder).map(Holder.Reference::getKey)); + } + + @SuppressWarnings("all") + public void addToTag(TagKey tag, Item... items){ + if(items.length == 0) return; + tag(tag).addAll(Arrays.stream(items).map(Item::builtInRegistryHolder).map(Holder.Reference::getKey)); + } +} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/worldgen/ModBiomeModifiers.java b/src/datagen/java/org/polaris2023/wildwind/hfas/worldgen/ModBiomeModifiers.java similarity index 84% rename from src/hfas/java/org/polaris2023/wildwind/hfas/worldgen/ModBiomeModifiers.java rename to src/datagen/java/org/polaris2023/wildwind/hfas/worldgen/ModBiomeModifiers.java index b78d09f..19add92 100644 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/worldgen/ModBiomeModifiers.java +++ b/src/datagen/java/org/polaris2023/wildwind/hfas/worldgen/ModBiomeModifiers.java @@ -18,7 +18,8 @@ import net.neoforged.neoforge.common.world.BiomeModifiers; import net.neoforged.neoforge.registries.NeoForgeRegistries; import org.polaris2023.wildwind.hfas.HFASMod; -import org.polaris2023.wildwind.hfas.registry.ModEntities; +import org.polaris2023.wildwind.wilderness.registry.ModEntities; +import org.polaris2023.wildwind.wilderness.tag.ModBiomeTags; /** * 生物群系修改器 @@ -41,6 +42,9 @@ public class ModBiomeModifiers { //那啥蟹生成 public static final ResourceKey ADD_MUDCRAB_SPAWNS = createKey("add_mudcrab_spawns"); + //食人鱼生成 + public static final ResourceKey ADD_PIRANHA_SPAWNS = createKey("add_piranha_spawns"); + public static void bootstrap(BootstrapContext context) { var placedFeatures = context.lookup(Registries.PLACED_FEATURE); var biomes = context.lookup(Registries.BIOME); @@ -80,6 +84,15 @@ public static void bootstrap(BootstrapContext context) { ) ) ); + + // 食人鱼生成 - 丛林与沼泽群系 + context.register(ADD_PIRANHA_SPAWNS, new BiomeModifiers.AddSpawnsBiomeModifier( + biomes.getOrThrow(ModBiomeTags.EntityGen.PIRANHA_SPAWNS), + WeightedList.builder() + .add(new MobSpawnSettings.SpawnerData(ModEntities.PIRANHA.get(), 1, 5), 8) + .build() + ) + ); } private static ResourceKey createKey(String name) { diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/worldgen/ModConfiguredFeatures.java b/src/datagen/java/org/polaris2023/wildwind/hfas/worldgen/ModConfiguredFeatures.java similarity index 87% rename from src/hfas/java/org/polaris2023/wildwind/hfas/worldgen/ModConfiguredFeatures.java rename to src/datagen/java/org/polaris2023/wildwind/hfas/worldgen/ModConfiguredFeatures.java index f79b37e..6ef14b2 100644 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/worldgen/ModConfiguredFeatures.java +++ b/src/datagen/java/org/polaris2023/wildwind/hfas/worldgen/ModConfiguredFeatures.java @@ -23,7 +23,6 @@ import net.minecraft.world.level.levelgen.feature.trunkplacers.BendingTrunkPlacer; import net.minecraft.world.level.levelgen.feature.trunkplacers.StraightTrunkPlacer; import org.polaris2023.wildwind.hfas.HFASMod; -import org.polaris2023.wildwind.hfas.block.ModBlocks; import java.util.Optional; @@ -37,18 +36,18 @@ public class ModConfiguredFeatures { public static final ResourceKey> BLAZE_TREE_KEY = ResourceKey.create( Registries.CONFIGURED_FEATURE, - Identifier.fromNamespaceAndPath(HFASMod.MOD_ID, "blaze_tree") + HFASMod.id("blaze_tree") ); public static final ResourceKey> SOUL_TREE_KEY = ResourceKey.create( Registries.CONFIGURED_FEATURE, - Identifier.fromNamespaceAndPath(HFASMod.MOD_ID, "soul_tree") + HFASMod.id("soul_tree") ); // 杜鹃树 - 使用杜鹃木原木 public static final ResourceKey> AZALEA_TREE_KEY = ResourceKey.create( Registries.CONFIGURED_FEATURE, - Identifier.fromNamespaceAndPath(HFASMod.MOD_ID, "azalea_tree") + HFASMod.id("azalea_tree") ); public static void bootstrap(BootstrapContext> context) { @@ -59,9 +58,9 @@ public static void bootstrap(BootstrapContext> context) // 焚烬木树 register(context, BLAZE_TREE_KEY, Feature.TREE, new TreeConfiguration.TreeConfigurationBuilder( - BlockStateProvider.simple(ModBlocks.BLAZE_LOG.get()), + BlockStateProvider.simple(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_LOG.get()), new StraightTrunkPlacer(4, 2, 0), - BlockStateProvider.simple(ModBlocks.BLAZE_LEAVES.get()), + BlockStateProvider.simple(org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_LEAVES.get()), new BlobFoliagePlacer(ConstantInt.of(2), ConstantInt.of(0), 3), new TwoLayersFeatureSize(1, 0, 1), belowTrunkProvider @@ -69,9 +68,9 @@ public static void bootstrap(BootstrapContext> context) // 灵焰木树 register(context, SOUL_TREE_KEY, Feature.TREE, new TreeConfiguration.TreeConfigurationBuilder( - BlockStateProvider.simple(ModBlocks.SOUL_LOG.get()), + BlockStateProvider.simple(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_LOG.get()), new StraightTrunkPlacer(4, 2, 0), - BlockStateProvider.simple(ModBlocks.SOUL_LEAVES.get()), + BlockStateProvider.simple(org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_LEAVES.get()), new BlobFoliagePlacer(ConstantInt.of(2), ConstantInt.of(0), 3), new TwoLayersFeatureSize(1, 0, 1), belowTrunkProvider @@ -79,7 +78,7 @@ public static void bootstrap(BootstrapContext> context) // 杜鹃树 - 使用杜鹃木原木和原版杜鹃树叶 register(context, AZALEA_TREE_KEY, Feature.TREE, new TreeConfiguration.TreeConfigurationBuilder( - BlockStateProvider.simple(ModBlocks.AZALEA_LOG.get()), + BlockStateProvider.simple(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_LOG.get()), new BendingTrunkPlacer(4, 2, 0, 3, UniformInt.of(1, 2)), new WeightedStateProvider( WeightedList.builder() diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/worldgen/ModPlacedFeatures.java b/src/datagen/java/org/polaris2023/wildwind/hfas/worldgen/ModPlacedFeatures.java similarity index 92% rename from src/hfas/java/org/polaris2023/wildwind/hfas/worldgen/ModPlacedFeatures.java rename to src/datagen/java/org/polaris2023/wildwind/hfas/worldgen/ModPlacedFeatures.java index b20b8ea..992272e 100644 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/worldgen/ModPlacedFeatures.java +++ b/src/datagen/java/org/polaris2023/wildwind/hfas/worldgen/ModPlacedFeatures.java @@ -30,18 +30,18 @@ public class ModPlacedFeatures { public static final ResourceKey BLAZE_TREE_PLACED_KEY = ResourceKey.create( Registries.PLACED_FEATURE, - Identifier.fromNamespaceAndPath(HFASMod.MOD_ID, "blaze_tree_placed") + HFASMod.id("blaze_tree_placed") ); public static final ResourceKey SOUL_TREE_PLACED_KEY = ResourceKey.create( Registries.PLACED_FEATURE, - Identifier.fromNamespaceAndPath(HFASMod.MOD_ID, "soul_tree_placed") + HFASMod.id("soul_tree_placed") ); // 杜鹃树放置 public static final ResourceKey AZALEA_TREE_PLACED_KEY = ResourceKey.create( Registries.PLACED_FEATURE, - Identifier.fromNamespaceAndPath(HFASMod.MOD_ID, "azalea_tree_placed") + HFASMod.id("azalea_tree_placed") ); public static void bootstrap(BootstrapContext context) { diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/HFASMod.java b/src/hfas/java/org/polaris2023/wildwind/hfas/HFASMod.java deleted file mode 100644 index 44d9621..0000000 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/HFASMod.java +++ /dev/null @@ -1,60 +0,0 @@ -package org.polaris2023.wildwind.hfas; - -import lombok.extern.slf4j.Slf4j; -import net.minecraft.resources.Identifier; -import net.neoforged.bus.api.IEventBus; -import net.neoforged.bus.api.SubscribeEvent; -import net.neoforged.fml.ModContainer; -import net.neoforged.fml.common.EventBusSubscriber; -import net.neoforged.fml.common.Mod; -import net.neoforged.neoforge.registries.DataPackRegistryEvent; -import org.polaris2023.wildwind.hfas.block.ModBlocks; -import org.polaris2023.wildwind.hfas.block.entity.ModBlockEntities; -import org.polaris2023.wildwind.hfas.config.ModCommonConfig; -import org.polaris2023.wildwind.hfas.entity.animal.MudcrabVariant; -import org.polaris2023.wildwind.hfas.menu.ModMenus; -import org.polaris2023.wildwind.hfas.registry.*; - -@Mod(HFASMod.MOD_ID) -@Slf4j -@EventBusSubscriber -public class HFASMod { - public static final String MOD_ID = "ww_hfas"; - - public HFASMod(IEventBus bus, ModContainer container) { - // 注册方块和物品 - ModBlocks.register(bus); - // 注册方块实体 - ModBlockEntities.register(bus); - // 注册菜单 - ModMenus.register(bus); - // 注册数据组件 - ModDataComponents.register(bus); - // 注册属性 - ModAttributes.register(bus); - - // 注册配置文件 - container.registerConfig(net.neoforged.fml.config.ModConfig.Type.COMMON, ModCommonConfig.SPEC); - - //注册物品 - ModItems.register(bus); - //注册创造模式物品栏 - ModCreativeTabs.register(bus); - - //-----[实体相关]----- - //实体信息同步器 - ModEntityDataSerializers.register(bus); - //注册实体类型 - ModEntities.register(bus); - } - - public static Identifier id(String path){ - return Identifier.fromNamespaceAndPath(MOD_ID,path); - } - - //数据驱动项注册 - @SubscribeEvent - public static void datapackRegistry(DataPackRegistryEvent.NewRegistry event){ - event.dataPackRegistry(DatadrivenRegistryKey.MUDCRAB_VARIANT, MudcrabVariant.DIRECT_CODEC, MudcrabVariant.NETWORK_CODEC); - } -} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/arrow/ArrowFletching.java b/src/hfas/java/org/polaris2023/wildwind/hfas/arrow/ArrowFletching.java deleted file mode 100644 index 98eb3a9..0000000 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/arrow/ArrowFletching.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.polaris2023.wildwind.hfas.arrow; - -import net.minecraft.world.item.Items; - -/** - * 箭羽类型枚举 - * 影响箭矢飞行速度 - * - * @author baka4n - * @since 2026/04/15 - */ -public enum ArrowFletching { - /** - * 羽毛 - 无效果(基准速度) - */ - FEATHER("feather", Items.FEATHER, 1.0F, "无效果"), - - /** - * 幻翼膜 - 飞行速度更快 - */ - PHANTOM_MEMBRANE("phantom_membrane", Items.PHANTOM_MEMBRANE, 1.5F, "飞行速度更快"); - - private final String name; - private final net.minecraft.world.level.ItemLike item; - private final float speedMultiplier; - private final String description; - - ArrowFletching(String name, net.minecraft.world.level.ItemLike item, float speedMultiplier, String description) { - this.name = name; - this.item = item; - this.speedMultiplier = speedMultiplier; - this.description = description; - } - - public String getName() { - return name; - } - - public net.minecraft.world.level.ItemLike getItem() { - return item; - } - - public float getSpeedMultiplier() { - return speedMultiplier; - } - - public String getDescription() { - return description; - } - - /** - * 根据物品获取对应的箭羽类型 - */ - public static ArrowFletching fromItem(net.minecraft.world.item.Item item) { - for (ArrowFletching fletching : values()) { - if (fletching.getItem().asItem() == item) { - return fletching; - } - } - return null; - } -} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/arrow/ArrowHead.java b/src/hfas/java/org/polaris2023/wildwind/hfas/arrow/ArrowHead.java deleted file mode 100644 index b21bc8f..0000000 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/arrow/ArrowHead.java +++ /dev/null @@ -1,107 +0,0 @@ -package org.polaris2023.wildwind.hfas.arrow; - -import net.minecraft.world.item.Items; - -/** - * 箭头类型枚举 - * 影响命中效果 - * - * @author baka4n - * @since 2026/04/15 - */ -public enum ArrowHead { - /** - * 燧石 - 无效果 - */ - FLINT("flint", Items.FLINT, false, "无效果"), - - /** - * 火药 - 爆炸,伤害不破坏地形 - */ - GUNPOWDER("gunpowder", Items.GUNPOWDER, false, "爆炸,伤害不破坏地形"), - - /** - * 粘液球 - 命中产生弹力 - */ - SLIME_BALL("slime_ball", Items.SLIME_BALL, false, "命中产生弹力"), - - /** - * 烈焰粉 - 命中致燃实体 - */ - BLAZE_POWDER("blaze_powder", Items.BLAZE_POWDER, false, "命中致燃实体"), - - /** - * 岩浆膏 - 致燃+弹力 - */ - MAGMA_CREAM("magma_cream", Items.MAGMA_CREAM, false, "致燃+弹力"), - - /** - * 风弹 - 风弹爆炸,不可回收 - */ - WIND_CHARGE("wind_charge", Items.WIND_CHARGE, true, "风弹爆炸,不可回收"), - - /** - * 煤炭 - 命中方块放置火把,不可回收 - */ - COAL("coal", Items.COAL, true, "命中方块放置火把,不可回收"), - - /** - * 紫颂果 - 目标随机传送,不可回收 - */ - CHORUS_FRUIT("chorus_fruit", Items.CHORUS_FRUIT, true, "目标随机传送,不可回收"), - - /** - * 末影之眼 - 与目标交换位置,不可回收 - */ - ENDER_EYE("ender_eye", Items.ENDER_EYE, true, "与目标交换位置,不可回收"), - - /** - * 紫水晶 - 破坏植物/玻璃类方块 - */ - AMETHYST_SHARD("amethyst_shard", Items.AMETHYST_SHARD, false, "破坏植物/玻璃类方块"), - - /** - * 海晶碎片 - 无视流体重力 - */ - PRISMARINE_SHARD("prismarine_shard", Items.PRISMARINE_SHARD, false, "无视流体重力"); - - private final String name; - private final net.minecraft.world.level.ItemLike item; - private final boolean notRecoverable; - private final String description; - - ArrowHead(String name, net.minecraft.world.level.ItemLike item, boolean notRecoverable, String description) { - this.name = name; - this.item = item; - this.notRecoverable = notRecoverable; - this.description = description; - } - - public String getName() { - return name; - } - - public net.minecraft.world.level.ItemLike getItem() { - return item; - } - - public boolean isNotRecoverable() { - return notRecoverable; - } - - public String getDescription() { - return description; - } - - /** - * 根据物品获取对应的箭头类型 - */ - public static ArrowHead fromItem(net.minecraft.world.item.Item item) { - for (ArrowHead head : values()) { - if (head.getItem().asItem() == item) { - return head; - } - } - return null; - } -} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/arrow/ArrowShaft.java b/src/hfas/java/org/polaris2023/wildwind/hfas/arrow/ArrowShaft.java deleted file mode 100644 index 6cde87d..0000000 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/arrow/ArrowShaft.java +++ /dev/null @@ -1,103 +0,0 @@ -package org.polaris2023.wildwind.hfas.arrow; - -import net.minecraft.world.item.Items; - -/** - * 箭杆类型枚举 - * 影响箭矢轨迹 - * - * @author baka4n - * @since 2026/04/15 - */ -public enum ArrowShaft { - /** - * 木棍 - 无效果 - */ - STICK("stick", Items.STICK, 1.0F, 0.0F, 0.0F, false, false, "无效果"), - - /** - * 烈焰棒 - 路径产生火焰粒子,落点生成火焰,不可回收 - */ - BLAZE_ROD("blaze_rod", Items.BLAZE_ROD, 1.0F, 0.0F, 0.0F, true, false, "路径产生火焰粒子,落点生成火焰,不可回收"), - - /** - * 风弹 - 非流体环境无重力,落点风弹爆炸,不可回收 - */ - WIND_CHARGE("wind_charge", Items.WIND_CHARGE, 1.0F, 0.0F, 0.0F, false, true, "非流体环境无重力,落点风弹爆炸,不可回收"), - - /** - * 骨头 - 下坠快,+1伤害,随机偏移大 - */ - BONE("bone", Items.BONE, 1.0F, 1.0F, 0.15F, false, false, "下坠快,+1伤害,随机偏移大"), - - /** - * 竹子 - 下坠慢,穿透1个目标,准度高 - */ - BAMBOO("bamboo", Items.BAMBOO, 0.7F, 0.0F, 0.0F, false, false, "下坠慢,穿透1个目标,准度高"); - - private final String name; - private final net.minecraft.world.level.ItemLike item; - private final float gravityMultiplier; - private final float damageBonus; - private final float inaccuracy; - private final boolean fireTrail; - private final boolean noGravity; - private final String description; - - ArrowShaft(String name, net.minecraft.world.level.ItemLike item, - float gravityMultiplier, float damageBonus, float inaccuracy, - boolean fireTrail, boolean noGravity, String description) { - this.name = name; - this.item = item; - this.gravityMultiplier = gravityMultiplier; - this.damageBonus = damageBonus; - this.inaccuracy = inaccuracy; - this.fireTrail = fireTrail; - this.noGravity = noGravity; - this.description = description; - } - - public String getName() { - return name; - } - - public net.minecraft.world.level.ItemLike getItem() { - return item; - } - - public float getGravityMultiplier() { - return gravityMultiplier; - } - - public float getDamageBonus() { - return damageBonus; - } - - public float getInaccuracy() { - return inaccuracy; - } - - public boolean hasFireTrail() { - return fireTrail; - } - - public boolean hasNoGravity() { - return noGravity; - } - - public String getDescription() { - return description; - } - - /** - * 根据物品获取对应的箭杆类型 - */ - public static ArrowShaft fromItem(net.minecraft.world.item.Item item) { - for (ArrowShaft shaft : values()) { - if (shaft.getItem().asItem() == item) { - return shaft; - } - } - return null; - } -} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/block/FletchingTableBlock.java b/src/hfas/java/org/polaris2023/wildwind/hfas/block/FletchingTableBlock.java deleted file mode 100644 index 8a7d9ce..0000000 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/block/FletchingTableBlock.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.polaris2023.wildwind.hfas.block; - -import net.minecraft.core.BlockPos; -import net.minecraft.network.chat.Component; -import net.minecraft.world.InteractionResult; -import net.minecraft.world.MenuProvider; -import net.minecraft.world.SimpleMenuProvider; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.EntityBlock; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.BlockHitResult; -import org.polaris2023.wildwind.hfas.block.entity.FletchingTableBlockEntity; -import org.polaris2023.wildwind.hfas.menu.FletchingTableMenu; - -import javax.annotation.Nullable; - -/** - * 制箭台方块 - 带有GUI功能 - * - * @author baka4n - * @since 2026/04/15 - */ -public class FletchingTableBlock extends Block implements EntityBlock { - private static final Component CONTAINER_TITLE = Component.translatable("container.fletching_table"); - - public FletchingTableBlock(Properties properties) { - super(properties); - } - - @Override - protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) { - if (level.isClientSide()) { - return InteractionResult.SUCCESS; - } - player.openMenu(state.getMenuProvider(level, pos)); - return InteractionResult.CONSUME; - } - - @Nullable - @Override - public MenuProvider getMenuProvider(BlockState state, Level level, BlockPos pos) { - return new SimpleMenuProvider( - (containerId, playerInventory, player) -> new FletchingTableMenu(containerId, playerInventory), - CONTAINER_TITLE - ); - } - - @Nullable - @Override - public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { - return new FletchingTableBlockEntity(pos, state); - } -} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/block/entity/FletchingTableBlockEntity.java b/src/hfas/java/org/polaris2023/wildwind/hfas/block/entity/FletchingTableBlockEntity.java deleted file mode 100644 index 11eaaed..0000000 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/block/entity/FletchingTableBlockEntity.java +++ /dev/null @@ -1,132 +0,0 @@ -package org.polaris2023.wildwind.hfas.block.entity; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.NonNullList; -import net.minecraft.world.Container; -import net.minecraft.world.ContainerHelper; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.inventory.Slot; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.storage.ValueInput; -import net.minecraft.world.level.storage.ValueOutput; - -/** - * 制箭台方块实体 - * - * @author baka4n - * @since 2026/04/15 - */ -public class FletchingTableBlockEntity extends BlockEntity implements Container { - public static int CONTAINER_SIZE = 0; - public enum Slots { - SLOT_FLETCHING, // 箭羽槽 - SLOT_SHAFT, // 箭羽槽 - SLOT_HEAD, // 箭头槽 - SLOT_FUEL, // 消耗槽 - SLOT_RESULT // 输出槽 - ; - - public final int slot; - - Slots() { - slot = CONTAINER_SIZE; - CONTAINER_SIZE++; - } - - public Slot toSlot(Container c, int x, int z) { - return new Slot(c, slot, x, z); - } - - public ItemStack remove(Container c, int size) { - return c.removeItem(slot, size); - } - } - - private final NonNullList items = NonNullList.withSize(CONTAINER_SIZE, ItemStack.EMPTY); - - - public FletchingTableBlockEntity(BlockPos pos, BlockState state) { - super(ModBlockEntities.FLETCHING_TABLE.get(), pos, state); - - } - - @Override - public int getContainerSize() { - return CONTAINER_SIZE; - } - - @Override - public boolean isEmpty() { - for (ItemStack stack : items) { - if (!stack.isEmpty()) { - return false; - } - } - return true; - } - - @Override - public ItemStack getItem(int slot) { - return slot >= 0 && slot < items.size() ? items.get(slot) : ItemStack.EMPTY; - } - - @Override - public ItemStack removeItem(int slot, int amount) { - return ContainerHelper.removeItem(items, slot, amount); - } - - @Override - public ItemStack removeItemNoUpdate(int slot) { - return ContainerHelper.takeItem(items, slot); - } - - @Override - public void setItem(int slot, ItemStack stack) { - if (slot >= 0 && slot < items.size()) { - items.set(slot, stack); - if (stack.getCount() > getMaxStackSize()) { - stack.setCount(getMaxStackSize()); - } - setChanged(); - } - } - - @Override - public void setChanged() { - super.setChanged(); - if (level != null) { - level.sendBlockUpdated(worldPosition, getBlockState(), getBlockState(), 3); - } - } - - @Override - public boolean stillValid(Player player) { - if (level == null) { - return false; - } - if (level.getBlockEntity(worldPosition) != this) { - return false; - } - return player.distanceToSqr(worldPosition.getX() + 0.5, worldPosition.getY() + 0.5, worldPosition.getZ() + 0.5) <= 64.0; - } - - @Override - public void clearContent() { - items.clear(); - setChanged(); - } - - @Override - protected void saveAdditional(ValueOutput output) { - super.saveAdditional(output); - ContainerHelper.saveAllItems(output, items); - } - - @Override - public void loadAdditional(ValueInput input) { - super.loadAdditional(input); - ContainerHelper.loadAllItems(input, items); - } -} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/block/entity/ModBlockEntities.java b/src/hfas/java/org/polaris2023/wildwind/hfas/block/entity/ModBlockEntities.java deleted file mode 100644 index d0ec8ef..0000000 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/block/entity/ModBlockEntities.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.polaris2023.wildwind.hfas.block.entity; - -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.world.level.block.entity.BlockEntityType; -import net.neoforged.bus.api.IEventBus; -import net.neoforged.neoforge.registries.DeferredHolder; -import net.neoforged.neoforge.registries.DeferredRegister; -import org.polaris2023.wildwind.hfas.HFASMod; -import org.polaris2023.wildwind.hfas.block.ModBlocks; - -/** - * 方块实体注册类 - * - * @author baka4n - * @since 2026/04/15 - */ -public class ModBlockEntities { - public static final DeferredRegister> BLOCK_ENTITIES = - DeferredRegister.create(BuiltInRegistries.BLOCK_ENTITY_TYPE, HFASMod.MOD_ID); - - // 制箭台方块实体 - public static final DeferredHolder, BlockEntityType> FLETCHING_TABLE = - BLOCK_ENTITIES.register( - "fletching_table", - () -> new BlockEntityType<>( - FletchingTableBlockEntity::new, - ModBlocks.FLETCHING_TABLE.get() - ) - ); - - public static void register(IEventBus bus) { - BLOCK_ENTITIES.register(bus); - } -} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/component/ArrowComponent.java b/src/hfas/java/org/polaris2023/wildwind/hfas/component/ArrowComponent.java deleted file mode 100644 index 8591db5..0000000 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/component/ArrowComponent.java +++ /dev/null @@ -1,124 +0,0 @@ -package org.polaris2023.wildwind.hfas.component; - -import com.mojang.serialization.Codec; -import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.minecraft.core.NonNullList; -import net.minecraft.network.RegistryFriendlyByteBuf; -import net.minecraft.network.codec.ByteBufCodecs; -import net.minecraft.network.codec.StreamCodec; -import net.minecraft.world.item.ItemStack; -import org.polaris2023.wildwind.hfas.arrow.ArrowFletching; -import org.polaris2023.wildwind.hfas.arrow.ArrowHead; -import org.polaris2023.wildwind.hfas.arrow.ArrowShaft; -import org.polaris2023.wildwind.hfas.registry.ModDataComponents; - -/** - * 箭矢组件数据 - * 存储箭羽、箭杆、箭头类型 - * - * @param fletching 箭羽类型 - * @param shaft 箭杆类型 - * @param head 箭头类型 - * @author baka4n - * @since 2026/04/15 - */ -public record ArrowComponent(ArrowFletching fletching, ArrowShaft shaft, ArrowHead head) { - - public static final Codec CODEC = RecordCodecBuilder.create(instance -> - instance.group( - Codec.STRING.xmap(ArrowFletching::valueOf, ArrowFletching::getName).fieldOf("fletching").forGetter(ArrowComponent::fletching), - Codec.STRING.xmap(ArrowShaft::valueOf, ArrowShaft::getName).fieldOf("shaft").forGetter(ArrowComponent::shaft), - Codec.STRING.xmap(ArrowHead::valueOf, ArrowHead::getName).fieldOf("head").forGetter(ArrowComponent::head) - ).apply(instance, ArrowComponent::new) - ); - - public static final StreamCodec STREAM_CODEC = StreamCodec.of( - (buf, component) -> { - buf.writeUtf(component.fletching().getName()); - buf.writeUtf(component.shaft().getName()); - buf.writeUtf(component.head().getName()); - }, - buf -> new ArrowComponent( - ArrowFletching.valueOf(buf.readUtf()), - ArrowShaft.valueOf(buf.readUtf()), - ArrowHead.valueOf(buf.readUtf()) - ) - ); - - /** - * 默认组件(普通箭矢) - */ - public static final ArrowComponent DEFAULT = new ArrowComponent( - ArrowFletching.FEATHER, - ArrowShaft.STICK, - ArrowHead.FLINT - ); - - /** - * 创建带组件的箭矢物品 - */ - public ItemStack createArrowStack(int count) { - ItemStack stack = new ItemStack(net.minecraft.world.item.Items.ARROW, count); - stack.set(ModDataComponents.ARROW_COMPONENT.get(), this); - return stack; - } - - /** - * 从物品获取箭矢组件 - */ - public static ArrowComponent fromStack(ItemStack stack) { - return stack.getOrDefault(ModDataComponents.ARROW_COMPONENT.get(), DEFAULT); - } - - /** - * 获取完整描述 - */ - public String getFullDescription() { - StringBuilder sb = new StringBuilder(); - if (fletching != ArrowFletching.FEATHER) { - sb.append("箭羽: ").append(fletching.getDescription()).append("\n"); - } - if (shaft != ArrowShaft.STICK) { - sb.append("箭杆: ").append(shaft.getDescription()).append("\n"); - } - if (head != ArrowHead.FLINT) { - sb.append("箭头: ").append(head.getDescription()); - } - return sb.toString().trim(); - } - - /** - * 是否不可回收 - */ - public boolean isNotRecoverable() { - return shaft.hasFireTrail() || shaft.hasNoGravity() || head.isNotRecoverable(); - } - - /** - * 获取飞行速度倍率 - */ - public float getSpeedMultiplier() { - return fletching.getSpeedMultiplier(); - } - - /** - * 获取重力倍率 - */ - public float getGravityMultiplier() { - return shaft.getGravityMultiplier(); - } - - /** - * 获取伤害加成 - */ - public float getDamageBonus() { - return shaft.getDamageBonus(); - } - - /** - * 获取不精确度 - */ - public float getInaccuracy() { - return shaft.getInaccuracy(); - } -} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/config/ModCommonConfig.java b/src/hfas/java/org/polaris2023/wildwind/hfas/config/ModCommonConfig.java deleted file mode 100644 index 43aa6df..0000000 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/config/ModCommonConfig.java +++ /dev/null @@ -1,59 +0,0 @@ -package org.polaris2023.wildwind.hfas.config; - -import net.neoforged.bus.api.SubscribeEvent; -import net.neoforged.fml.common.EventBusSubscriber; -import net.neoforged.fml.event.config.ModConfigEvent; -import net.neoforged.neoforge.common.ModConfigSpec; -import org.polaris2023.wildwind.hfas.HFASMod; - -/** - * 模组配置类 - * 用于控制模组行为的各种配置选项 - * - * @author baka4n - * @since 2026/04/15 - */ -@EventBusSubscriber(modid = HFASMod.MOD_ID) -public class ModCommonConfig { - - private static final ModConfigSpec.Builder BUILDER = new ModConfigSpec.Builder(); - - // ==================== 世界生成配置 ==================== - - /** - * 是否启用原版制箭台替换为模组制箭台 - * 当设置为 false 时,世界生成时不会替换原版制箭台 - */ - private static final ModConfigSpec.BooleanValue REPLACE_VANILLA_FLETCHING_TABLE = BUILDER - .comment("是否启用原版制箭台替换为模组制箭台", - "当设置为 false 时,世界生成时不会替换原版制箭台", - "Enable replacement of vanilla fletching table with mod fletching table", - "When set to false, vanilla fletching tables will not be replaced during world generation") - .define("worldgen.replaceVanillaFletchingTable", true); - - // ==================== 构建配置规范 ==================== - - public static final ModConfigSpec SPEC = BUILDER.build(); - - // ==================== 运行时配置值 ==================== - - private static boolean replaceVanillaFletchingTable = true; - - /** - * 获取是否启用原版制箭台替换 - * @return true 表示启用替换,false 表示不替换 - */ - public static boolean shouldReplaceVanillaFletchingTable() { - return replaceVanillaFletchingTable; - } - - /** - * 配置加载事件处理 - * 当配置文件被加载或重新加载时调用 - */ - @SubscribeEvent - static void onLoad(final ModConfigEvent event) { - // 更新运行时配置值 - replaceVanillaFletchingTable = REPLACE_VANILLA_FLETCHING_TABLE.get(); - } -} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/datagen/provider/ModDataMapsProvider.java b/src/hfas/java/org/polaris2023/wildwind/hfas/datagen/provider/ModDataMapsProvider.java deleted file mode 100644 index 05d0b5b..0000000 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/datagen/provider/ModDataMapsProvider.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.polaris2023.wildwind.hfas.datagen.provider; - -import net.minecraft.core.HolderLookup; -import net.minecraft.data.PackOutput; -import net.neoforged.neoforge.common.data.DataMapProvider; -import net.neoforged.neoforge.registries.datamaps.builtin.NeoForgeDataMaps; -import net.neoforged.neoforge.registries.datamaps.builtin.Strippable; -import org.polaris2023.wildwind.hfas.block.ModBlocks; - -import java.util.concurrent.CompletableFuture; - -public class ModDataMapsProvider extends DataMapProvider { - /** - * Create a new provider. - * - * @param packOutput the output location - * @param lookupProvider a {@linkplain CompletableFuture} supplying the registries - */ - public ModDataMapsProvider(PackOutput packOutput, CompletableFuture lookupProvider) { - super(packOutput, lookupProvider); - } - - @Override - protected void gather(HolderLookup.Provider provider) { - builder(NeoForgeDataMaps.STRIPPABLES) - .add(ModBlocks.AZALEA_LOG.getKey(), new Strippable(ModBlocks.STRIPPED_AZALEA_LOG.get()), false) - .add(ModBlocks.AZALEA_WOOD.getKey(), new Strippable(ModBlocks.STRIPPED_AZALEA_WOOD.get()), false) - .add(ModBlocks.BLAZE_LOG.getKey(), new Strippable(ModBlocks.STRIPPED_BLAZE_LOG.get()), false) - .add(ModBlocks.BLAZE_WOOD.getKey(), new Strippable(ModBlocks.STRIPPED_BLAZE_WOOD.get()), false) - .add(ModBlocks.SOUL_LOG.getKey(), new Strippable(ModBlocks.STRIPPED_SOUL_LOG.get()), false) - .add(ModBlocks.SOUL_WOOD.getKey(), new Strippable(ModBlocks.STRIPPED_SOUL_WOOD.get()), false) - ; - } -} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/datagen/provider/ModModelProvider.java b/src/hfas/java/org/polaris2023/wildwind/hfas/datagen/provider/ModModelProvider.java deleted file mode 100644 index e6196de..0000000 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/datagen/provider/ModModelProvider.java +++ /dev/null @@ -1,174 +0,0 @@ -package org.polaris2023.wildwind.hfas.datagen.provider; - -import net.minecraft.client.data.models.BlockModelGenerators; -import net.minecraft.client.data.models.ItemModelGenerators; -import net.minecraft.client.data.models.ModelProvider; -import net.minecraft.client.data.models.model.ItemModelUtils; -import net.minecraft.client.data.models.model.ModelLocationUtils; -import net.minecraft.client.data.models.model.ModelTemplate; -import net.minecraft.client.data.models.model.ModelTemplates; -import net.minecraft.client.data.models.model.TexturedModel; -import net.minecraft.data.PackOutput; -import net.minecraft.world.item.Item; -import net.minecraft.world.level.block.Block; -import org.polaris2023.wildwind.hfas.HFASMod; -import org.polaris2023.wildwind.hfas.block.ModBlocks; -import org.polaris2023.wildwind.hfas.registry.ModItems; - -import java.util.function.Supplier; - -/** - * 模型生成器 - * 用于生成方块和物品的模型文件 - * - * @author baka4n - * @since 2026/04/15 - */ -public class ModModelProvider extends ModelProvider { - - public ModModelProvider(PackOutput output) { - super(output, HFASMod.MOD_ID); - } - - @Override - protected void registerModels(BlockModelGenerators blockModels, ItemModelGenerators itemModels) { - // ==================== 焚烬木套件 ==================== - registerWoodModels(blockModels, itemModels, - ModBlocks.BLAZE_LOG.get(), - ModBlocks.BLAZE_WOOD.get(), - ModBlocks.STRIPPED_BLAZE_LOG.get(), - ModBlocks.STRIPPED_BLAZE_WOOD.get(), - ModBlocks.BLAZE_PLANKS.get(), - ModBlocks.BLAZE_STAIRS.get(), - ModBlocks.BLAZE_SLAB.get(), - ModBlocks.BLAZE_FENCE.get(), - ModBlocks.BLAZE_FENCE_GATE.get(), - ModBlocks.BLAZE_DOOR.get(), - ModBlocks.BLAZE_TRAPDOOR.get(), - ModBlocks.BLAZE_PRESSURE_PLATE.get(), - ModBlocks.BLAZE_BUTTON.get() - ); - // 焚烬木树叶 - 橙色染色 - blockModels.createTintedLeaves(ModBlocks.BLAZE_LEAVES.get(), TexturedModel.LEAVES, 0xFF8000); - // 焚烬木树苗 - blockModels.createCrossBlock(ModBlocks.BLAZE_SAPLING.get(), BlockModelGenerators.PlantType.NOT_TINTED); - - // ==================== 灵焰木套件 ==================== - registerWoodModels(blockModels, itemModels, - ModBlocks.SOUL_LOG.get(), - ModBlocks.SOUL_WOOD.get(), - ModBlocks.STRIPPED_SOUL_LOG.get(), - ModBlocks.STRIPPED_SOUL_WOOD.get(), - ModBlocks.SOUL_PLANKS.get(), - ModBlocks.SOUL_STAIRS.get(), - ModBlocks.SOUL_SLAB.get(), - ModBlocks.SOUL_FENCE.get(), - ModBlocks.SOUL_FENCE_GATE.get(), - ModBlocks.SOUL_DOOR.get(), - ModBlocks.SOUL_TRAPDOOR.get(), - ModBlocks.SOUL_PRESSURE_PLATE.get(), - ModBlocks.SOUL_BUTTON.get() - ); - // 灵焰木树叶 - 青色染色 - blockModels.createTintedLeaves(ModBlocks.SOUL_LEAVES.get(), TexturedModel.LEAVES, 0x00FFFF); - // 灵焰木树苗 - blockModels.createCrossBlock(ModBlocks.SOUL_SAPLING.get(), BlockModelGenerators.PlantType.NOT_TINTED); - - // ==================== 杜鹃木套件 ==================== - registerWoodModels(blockModels, itemModels, - ModBlocks.AZALEA_LOG.get(), - ModBlocks.AZALEA_WOOD.get(), - ModBlocks.STRIPPED_AZALEA_LOG.get(), - ModBlocks.STRIPPED_AZALEA_WOOD.get(), - ModBlocks.AZALEA_PLANKS.get(), - ModBlocks.AZALEA_STAIRS.get(), - ModBlocks.AZALEA_SLAB.get(), - ModBlocks.AZALEA_FENCE.get(), - ModBlocks.AZALEA_FENCE_GATE.get(), - ModBlocks.AZALEA_DOOR.get(), - ModBlocks.AZALEA_TRAPDOOR.get(), - ModBlocks.AZALEA_PRESSURE_PLATE.get(), - ModBlocks.AZALEA_BUTTON.get() - ); - - // ==================== 其他方块 ==================== - // 焦灰草方块 - 使用简单的方块模型 - createSimpleBlock(blockModels, ModBlocks.SCORCHED_GRASS_BLOCK.get()); - - // 焦土 - 使用简单的方块模型 - createSimpleBlock(blockModels, ModBlocks.SCORCHED_DIRT.get()); - - // 焦灰草丛 - 使用交叉模型(类似草丛) - createCrossBlock(blockModels, ModBlocks.SCORCHED_GRASS.get()); - - // 焦灰枝条 - 使用交叉模型 - createCrossBlock(blockModels, ModBlocks.SCORCHED_TWIG.get()); - - // 仙人球 - 使用交叉模型 - createCrossBlock(blockModels, ModBlocks.TINY_CACTUS.get()); - - // 制箭台 - 使用简单方块模型 - createSimpleBlock(blockModels, ModBlocks.FLETCHING_TABLE.get()); - - // ==================== 独立物品 ==================== - simpleItem(itemModels, ModItems.CRAB_CLAW); - - // 万用蟹钳 - 使用手写 3D 模型(resources 下的 models/item/omni_claw.json),仅生成物品模型定义 - itemModels.itemModelOutput.accept( - ModItems.OMNI_CLAW.get(), - ItemModelUtils.plainModel(ModelLocationUtils.getModelLocation(ModItems.OMNI_CLAW.get())) - ); - simpleItem(itemModels, ModItems.MUDCRAB_BUCKET); - simpleItem(itemModels, ModItems.MUDCRAB_SPAWN_EGG); - } - - /** - * 注册木质方块模型 - */ - private void registerWoodModels(BlockModelGenerators blockModels, ItemModelGenerators itemModels, - Block log, Block wood, - Block strippedLog, Block strippedWood, - Block planks, Block stairs, Block slab, - Block fence, Block fenceGate, - Block door, Block trapdoor, - Block pressurePlate, Block button) { - // 原木 - 使用 WoodProvider(自动生成物品模型) - blockModels.woodProvider(log).logWithHorizontal(log).wood(wood); - - // 去皮原木(自动生成物品模型) - blockModels.woodProvider(strippedLog).logWithHorizontal(strippedLog).wood(strippedWood); - - // 使用 family 创建木质方块套件(包括木板,自动生成物品模型) - blockModels.family(planks) - .stairs(stairs) - .slab(slab) - .fence(fence) - .fenceGate(fenceGate) - .pressurePlate(pressurePlate) - .button(button); - - // 门(自动生成物品模型) - blockModels.createDoor(door); - - // 活板门(自动生成物品模型) - blockModels.createTrapdoor(trapdoor); - } - - /** - * 创建简单方块模型(六面相同贴图) - */ - private void createSimpleBlock(BlockModelGenerators blockModels, Block block) { - blockModels.createTrivialCube(block); - } - - /** - * 创建交叉模型(用于植物类方块) - */ - private void createCrossBlock(BlockModelGenerators blockModels, Block block) { - blockModels.createCrossBlock(block, BlockModelGenerators.PlantType.NOT_TINTED); - } - - private void simpleItem(ItemModelGenerators itemModels, Supplier item){ - itemModels.generateFlatItem(item.get(), ModelTemplates.FLAT_ITEM); - } -} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/datagen/provider/ModRecipeProvider.java b/src/hfas/java/org/polaris2023/wildwind/hfas/datagen/provider/ModRecipeProvider.java deleted file mode 100644 index 7af14cc..0000000 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/datagen/provider/ModRecipeProvider.java +++ /dev/null @@ -1,73 +0,0 @@ -package org.polaris2023.wildwind.hfas.datagen.provider; - -import net.minecraft.core.HolderLookup; -import net.minecraft.data.PackOutput; -import net.minecraft.data.recipes.RecipeOutput; -import net.minecraft.data.recipes.ShapedRecipeBuilder; -import net.minecraft.data.recipes.RecipeProvider; -import net.minecraft.data.recipes.RecipeCategory; -import net.minecraft.resources.ResourceKey; -import net.minecraft.world.item.Items; -import net.minecraft.world.item.crafting.Ingredient; -import net.minecraft.world.item.crafting.Recipe; -import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; -import org.polaris2023.wildwind.hfas.HFASMod; -import org.polaris2023.wildwind.hfas.arrow.ArrowFletching; -import org.polaris2023.wildwind.hfas.arrow.ArrowHead; -import org.polaris2023.wildwind.hfas.arrow.ArrowShaft; -import org.polaris2023.wildwind.hfas.component.ArrowComponent; -import org.polaris2023.wildwind.hfas.registry.ModItems; - -import java.util.concurrent.CompletableFuture; - -/** - * 箭矢配方数据生成器 - * - * @author baka4n - * @since 2026/04/15 - */ -public class ModRecipeProvider extends RecipeProvider { - - - protected ModRecipeProvider(HolderLookup.Provider registries, RecipeOutput output) { - super(registries, output); - } - - @Override - protected void buildRecipes() { - // 生成所有箭矢组合配方 - generateArrowRecipes(); - // 万用蟹钳:铜锭x6 + 蟹钳x3 - ShapedRecipeBuilder.shaped(this.items, RecipeCategory.TOOLS, ModItems.OMNI_CLAW.get()) - .define('I', Items.COPPER_INGOT) - .define('C', ModItems.CRAB_CLAW.get()) - .pattern("ICC") - .pattern("IIC") - .pattern("III") - .unlockedBy("has_" + ModItems.CRAB_CLAW.getId().getPath(), this.has(ModItems.OMNI_CLAW.get())) - .save(this.output); - } - - private void generateArrowRecipes() { - - } - - public static class Runner extends RecipeProvider.Runner { - - public Runner(PackOutput packOutput, CompletableFuture registries) { - super(packOutput, registries); - } - - @Override - protected RecipeProvider createRecipeProvider(HolderLookup.Provider provider, RecipeOutput recipeOutput) { - return new ModRecipeProvider(provider, recipeOutput); - } - - @Override - public String getName() { - return "Wild Wind " + HFASMod.MOD_ID + " Recipe Provider"; - } - } - - -} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/datagen/provider/lang/EnUsLanguageProvider.java b/src/hfas/java/org/polaris2023/wildwind/hfas/datagen/provider/lang/EnUsLanguageProvider.java deleted file mode 100644 index ea00fa7..0000000 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/datagen/provider/lang/EnUsLanguageProvider.java +++ /dev/null @@ -1,89 +0,0 @@ -package org.polaris2023.wildwind.hfas.datagen.provider.lang; - -import net.minecraft.data.PackOutput; -import net.neoforged.neoforge.common.data.LanguageProvider; -import org.polaris2023.wildwind.hfas.HFASMod; -import org.polaris2023.wildwind.hfas.block.ModBlocks; - -/** - * 英语语言文件生成器 - * - * @author baka4n - * @since 2026/04/15 - */ -public class EnUsLanguageProvider extends LanguageProvider { - - public EnUsLanguageProvider(PackOutput output) { - super(output, HFASMod.MOD_ID, "en_us"); - } - - @Override - protected void addTranslations() { - // 焚烬木套件 - addBlock(ModBlocks.BLAZE_LOG, "Blaze Log"); - addBlock(ModBlocks.BLAZE_WOOD, "Blaze Wood"); - addBlock(ModBlocks.STRIPPED_BLAZE_LOG, "Stripped Blaze Log"); - addBlock(ModBlocks.STRIPPED_BLAZE_WOOD, "Stripped Blaze Wood"); - addBlock(ModBlocks.BLAZE_PLANKS, "Blaze Planks"); - addBlock(ModBlocks.BLAZE_STAIRS, "Blaze Stairs"); - addBlock(ModBlocks.BLAZE_SLAB, "Blaze Slab"); - addBlock(ModBlocks.BLAZE_FENCE, "Blaze Fence"); - addBlock(ModBlocks.BLAZE_FENCE_GATE, "Blaze Fence Gate"); - addBlock(ModBlocks.BLAZE_DOOR, "Blaze Door"); - addBlock(ModBlocks.BLAZE_TRAPDOOR, "Blaze Trapdoor"); - addBlock(ModBlocks.BLAZE_PRESSURE_PLATE, "Blaze Pressure Plate"); - addBlock(ModBlocks.BLAZE_BUTTON, "Blaze Button"); - addBlock(ModBlocks.BLAZE_LEAVES, "Blaze Leaves"); - addBlock(ModBlocks.BLAZE_SAPLING, "Blaze Sapling"); - - // 灵焰木套件 - addBlock(ModBlocks.SOUL_LOG, "Soul Log"); - addBlock(ModBlocks.SOUL_WOOD, "Soul Wood"); - addBlock(ModBlocks.STRIPPED_SOUL_LOG, "Stripped Soul Log"); - addBlock(ModBlocks.STRIPPED_SOUL_WOOD, "Stripped Soul Wood"); - addBlock(ModBlocks.SOUL_PLANKS, "Soul Planks"); - addBlock(ModBlocks.SOUL_STAIRS, "Soul Stairs"); - addBlock(ModBlocks.SOUL_SLAB, "Soul Slab"); - addBlock(ModBlocks.SOUL_FENCE, "Soul Fence"); - addBlock(ModBlocks.SOUL_FENCE_GATE, "Soul Fence Gate"); - addBlock(ModBlocks.SOUL_DOOR, "Soul Door"); - addBlock(ModBlocks.SOUL_TRAPDOOR, "Soul Trapdoor"); - addBlock(ModBlocks.SOUL_PRESSURE_PLATE, "Soul Pressure Plate"); - addBlock(ModBlocks.SOUL_BUTTON, "Soul Button"); - addBlock(ModBlocks.SOUL_LEAVES, "Soul Leaves"); - addBlock(ModBlocks.SOUL_SAPLING, "Soul Sapling"); - - // 杜鹃木套件 - addBlock(ModBlocks.AZALEA_LOG, "Azalea Log"); - addBlock(ModBlocks.AZALEA_WOOD, "Azalea Wood"); - addBlock(ModBlocks.STRIPPED_AZALEA_LOG, "Stripped Azalea Log"); - addBlock(ModBlocks.STRIPPED_AZALEA_WOOD, "Stripped Azalea Wood"); - addBlock(ModBlocks.AZALEA_PLANKS, "Azalea Planks"); - addBlock(ModBlocks.AZALEA_STAIRS, "Azalea Stairs"); - addBlock(ModBlocks.AZALEA_SLAB, "Azalea Slab"); - addBlock(ModBlocks.AZALEA_FENCE, "Azalea Fence"); - addBlock(ModBlocks.AZALEA_FENCE_GATE, "Azalea Fence Gate"); - addBlock(ModBlocks.AZALEA_DOOR, "Azalea Door"); - addBlock(ModBlocks.AZALEA_TRAPDOOR, "Azalea Trapdoor"); - addBlock(ModBlocks.AZALEA_PRESSURE_PLATE, "Azalea Pressure Plate"); - addBlock(ModBlocks.AZALEA_BUTTON, "Azalea Button"); - - // 其他方块 - addBlock(ModBlocks.SCORCHED_GRASS_BLOCK, "Scorched Grass Block"); - addBlock(ModBlocks.SCORCHED_DIRT, "Scorched Dirt"); - addBlock(ModBlocks.SCORCHED_GRASS, "Scorched Grass"); - addBlock(ModBlocks.SCORCHED_TWIG, "Scorched Twig"); - addBlock(ModBlocks.TINY_CACTUS, "Tiny Cactus"); - addBlock(ModBlocks.FLETCHING_TABLE, "Fletching Table"); - - // GUI - add("container.fletching_table", "Fletching Table"); - // 属性 - add("attributes.ww_hfas.extra_item_pickup_range", "Extra Item Pickup Range"); - - //创造模式物品栏 - add("mod.wild_wind.name", "Wild Wind"); - - ZhEnCombineLangProvider.addLang(this, "en_us"); - } -} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/datagen/provider/lang/ZhCnLanguageProvider.java b/src/hfas/java/org/polaris2023/wildwind/hfas/datagen/provider/lang/ZhCnLanguageProvider.java deleted file mode 100644 index 85b60e7..0000000 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/datagen/provider/lang/ZhCnLanguageProvider.java +++ /dev/null @@ -1,93 +0,0 @@ -package org.polaris2023.wildwind.hfas.datagen.provider.lang; - -import net.minecraft.data.PackOutput; -import net.neoforged.neoforge.common.data.LanguageProvider; -import org.polaris2023.wildwind.hfas.HFASMod; -import org.polaris2023.wildwind.hfas.block.ModBlocks; -import org.polaris2023.wildwind.hfas.registry.ModItems; - -/** - * 中文语言文件生成器 - * - * @author baka4n - * @since 2026/04/15 - */ -public class ZhCnLanguageProvider extends LanguageProvider { - - public ZhCnLanguageProvider(PackOutput output) { - super(output, HFASMod.MOD_ID, "zh_cn"); - } - - @Override - protected void addTranslations() { - // 焚烬木套件 - addBlock(ModBlocks.BLAZE_LOG, "焚烬木原木"); - addBlock(ModBlocks.BLAZE_WOOD, "焚烬木"); - addBlock(ModBlocks.STRIPPED_BLAZE_LOG, "去皮焚烬木原木"); - addBlock(ModBlocks.STRIPPED_BLAZE_WOOD, "去皮焚烬木"); - addBlock(ModBlocks.BLAZE_PLANKS, "焚烬木木板"); - addBlock(ModBlocks.BLAZE_STAIRS, "焚烬木楼梯"); - addBlock(ModBlocks.BLAZE_SLAB, "焚烬木台阶"); - addBlock(ModBlocks.BLAZE_FENCE, "焚烬木栅栏"); - addBlock(ModBlocks.BLAZE_FENCE_GATE, "焚烬木栅栏门"); - addBlock(ModBlocks.BLAZE_DOOR, "焚烬木门"); - addBlock(ModBlocks.BLAZE_TRAPDOOR, "焚烬木活板门"); - addBlock(ModBlocks.BLAZE_PRESSURE_PLATE, "焚烬木压力板"); - addBlock(ModBlocks.BLAZE_BUTTON, "焚烬木按钮"); - addBlock(ModBlocks.BLAZE_LEAVES, "焚烬木树叶"); - addBlock(ModBlocks.BLAZE_SAPLING, "焚烬木树苗"); - - // 灵焰木套件 - addBlock(ModBlocks.SOUL_LOG, "灵焰木原木"); - addBlock(ModBlocks.SOUL_WOOD, "灵焰木"); - addBlock(ModBlocks.STRIPPED_SOUL_LOG, "去皮灵焰木原木"); - addBlock(ModBlocks.STRIPPED_SOUL_WOOD, "去皮灵焰木"); - addBlock(ModBlocks.SOUL_PLANKS, "灵焰木木板"); - addBlock(ModBlocks.SOUL_STAIRS, "灵焰木楼梯"); - addBlock(ModBlocks.SOUL_SLAB, "灵焰木台阶"); - addBlock(ModBlocks.SOUL_FENCE, "灵焰木栅栏"); - addBlock(ModBlocks.SOUL_FENCE_GATE, "灵焰木栅栏门"); - addBlock(ModBlocks.SOUL_DOOR, "灵焰木门"); - addBlock(ModBlocks.SOUL_TRAPDOOR, "灵焰木活板门"); - addBlock(ModBlocks.SOUL_PRESSURE_PLATE, "灵焰木压力板"); - addBlock(ModBlocks.SOUL_BUTTON, "灵焰木按钮"); - addBlock(ModBlocks.SOUL_LEAVES, "灵焰木树叶"); - addBlock(ModBlocks.SOUL_SAPLING, "灵焰木树苗"); - - // 杜鹃木套件 - addBlock(ModBlocks.AZALEA_LOG, "杜鹃木原木"); - addBlock(ModBlocks.AZALEA_WOOD, "杜鹃木"); - addBlock(ModBlocks.STRIPPED_AZALEA_LOG, "去皮杜鹃木原木"); - addBlock(ModBlocks.STRIPPED_AZALEA_WOOD, "去皮杜鹃木"); - addBlock(ModBlocks.AZALEA_PLANKS, "杜鹃木木板"); - addBlock(ModBlocks.AZALEA_STAIRS, "杜鹃木楼梯"); - addBlock(ModBlocks.AZALEA_SLAB, "杜鹃木台阶"); - addBlock(ModBlocks.AZALEA_FENCE, "杜鹃木栅栏"); - addBlock(ModBlocks.AZALEA_FENCE_GATE, "杜鹃木栅栏门"); - addBlock(ModBlocks.AZALEA_DOOR, "杜鹃木门"); - addBlock(ModBlocks.AZALEA_TRAPDOOR, "杜鹃木活板门"); - addBlock(ModBlocks.AZALEA_PRESSURE_PLATE, "杜鹃木压力板"); - addBlock(ModBlocks.AZALEA_BUTTON, "杜鹃木按钮"); - - // 其他方块 - addBlock(ModBlocks.SCORCHED_GRASS_BLOCK, "焦灰草方块"); - addBlock(ModBlocks.SCORCHED_DIRT, "焦土"); - addBlock(ModBlocks.SCORCHED_GRASS, "焦灰草丛"); - addBlock(ModBlocks.SCORCHED_TWIG, "焦灰枝条"); - addBlock(ModBlocks.TINY_CACTUS, "仙人球"); - addBlock(ModBlocks.FLETCHING_TABLE, "制箭台"); - - // GUI - add("container.fletching_table", "制箭台"); - // 属性 - add("attributes.ww_hfas.extra_item_pickup_range", "额外物品拾取距离"); - - //创造模式物品栏 - add("mod.wild_wind.name", "原野之风"); - - ZhEnCombineLangProvider.addLang(this, "zh_cn"); - - } - - -} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/datagen/provider/loot/BlockLoot.java b/src/hfas/java/org/polaris2023/wildwind/hfas/datagen/provider/loot/BlockLoot.java deleted file mode 100644 index 81fc0f7..0000000 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/datagen/provider/loot/BlockLoot.java +++ /dev/null @@ -1,87 +0,0 @@ -package org.polaris2023.wildwind.hfas.datagen.provider.loot; - -import net.minecraft.core.HolderLookup; -import net.minecraft.data.loot.BlockLootSubProvider; -import net.minecraft.world.flag.FeatureFlags; -import net.minecraft.world.item.Items; -import net.minecraft.world.level.block.Block; -import org.jspecify.annotations.NonNull; -import org.polaris2023.wildwind.hfas.block.ModBlocks; - -import java.util.Set; - -public class BlockLoot extends BlockLootSubProvider { - public BlockLoot(HolderLookup.Provider registries) { - super(Set.of(), FeatureFlags.DEFAULT_FLAGS, registries); - } - - @Override - protected @NonNull Iterable getKnownBlocks() { - return ModBlocks.BLOCKS.getEntries().stream().map(h -> (Block) h.value()).toList(); - } - - @Override - protected void generate() { - // 焚烬木套件 - dropSelf(ModBlocks.BLAZE_LOG.get()); - dropSelf(ModBlocks.BLAZE_WOOD.get()); - dropSelf(ModBlocks.STRIPPED_BLAZE_LOG.get()); - dropSelf(ModBlocks.STRIPPED_BLAZE_WOOD.get()); - dropSelf(ModBlocks.BLAZE_PLANKS.get()); - dropSelf(ModBlocks.BLAZE_STAIRS.get()); - dropSelf(ModBlocks.BLAZE_SLAB.get()); - dropSelf(ModBlocks.BLAZE_FENCE.get()); - dropSelf(ModBlocks.BLAZE_FENCE_GATE.get()); - dropSelf(ModBlocks.BLAZE_PRESSURE_PLATE.get()); - dropSelf(ModBlocks.BLAZE_BUTTON.get()); - // 树叶 - 使用树叶掉落逻辑 - add(ModBlocks.BLAZE_LEAVES.get(), createLeavesDrops(ModBlocks.BLAZE_LEAVES.get(), ModBlocks.BLAZE_SAPLING.get(), 0.05F)); - dropSelf(ModBlocks.BLAZE_SAPLING.get()); - // 门需要特殊处理 - add(ModBlocks.BLAZE_DOOR.get(), createDoorTable(ModBlocks.BLAZE_DOOR.get())); - add(ModBlocks.BLAZE_TRAPDOOR.get(), createDoorTable(ModBlocks.BLAZE_TRAPDOOR.get())); - - // 灵焰木套件 - dropSelf(ModBlocks.SOUL_LOG.get()); - dropSelf(ModBlocks.SOUL_WOOD.get()); - dropSelf(ModBlocks.STRIPPED_SOUL_LOG.get()); - dropSelf(ModBlocks.STRIPPED_SOUL_WOOD.get()); - dropSelf(ModBlocks.SOUL_PLANKS.get()); - dropSelf(ModBlocks.SOUL_STAIRS.get()); - dropSelf(ModBlocks.SOUL_SLAB.get()); - dropSelf(ModBlocks.SOUL_FENCE.get()); - dropSelf(ModBlocks.SOUL_FENCE_GATE.get()); - dropSelf(ModBlocks.SOUL_PRESSURE_PLATE.get()); - dropSelf(ModBlocks.SOUL_BUTTON.get()); - // 树叶 - 使用树叶掉落逻辑 - add(ModBlocks.SOUL_LEAVES.get(), createLeavesDrops(ModBlocks.SOUL_LEAVES.get(), ModBlocks.SOUL_SAPLING.get(), 0.05F)); - dropSelf(ModBlocks.SOUL_SAPLING.get()); - // 门需要特殊处理 - add(ModBlocks.SOUL_DOOR.get(), createDoorTable(ModBlocks.SOUL_DOOR.get())); - add(ModBlocks.SOUL_TRAPDOOR.get(), createDoorTable(ModBlocks.SOUL_TRAPDOOR.get())); - - // 杜鹃木套件 - dropSelf(ModBlocks.AZALEA_LOG.get()); - dropSelf(ModBlocks.AZALEA_WOOD.get()); - dropSelf(ModBlocks.STRIPPED_AZALEA_LOG.get()); - dropSelf(ModBlocks.STRIPPED_AZALEA_WOOD.get()); - dropSelf(ModBlocks.AZALEA_PLANKS.get()); - dropSelf(ModBlocks.AZALEA_STAIRS.get()); - dropSelf(ModBlocks.AZALEA_SLAB.get()); - dropSelf(ModBlocks.AZALEA_FENCE.get()); - dropSelf(ModBlocks.AZALEA_FENCE_GATE.get()); - dropSelf(ModBlocks.AZALEA_PRESSURE_PLATE.get()); - dropSelf(ModBlocks.AZALEA_BUTTON.get()); - // 门需要特殊处理 - add(ModBlocks.AZALEA_DOOR.get(), createDoorTable(ModBlocks.AZALEA_DOOR.get())); - add(ModBlocks.AZALEA_TRAPDOOR.get(), createDoorTable(ModBlocks.AZALEA_TRAPDOOR.get())); - - // 其他方块 - dropSelf(ModBlocks.SCORCHED_GRASS_BLOCK.get()); - dropSelf(ModBlocks.SCORCHED_DIRT.get()); - dropSelf(ModBlocks.SCORCHED_GRASS.get()); - dropSelf(ModBlocks.SCORCHED_TWIG.get()); - dropSelf(ModBlocks.TINY_CACTUS.get()); - dropOther(ModBlocks.FLETCHING_TABLE.get(), Items.FLETCHING_TABLE); - } -} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/datagen/provider/tag/ModItemTagsProvider.java b/src/hfas/java/org/polaris2023/wildwind/hfas/datagen/provider/tag/ModItemTagsProvider.java deleted file mode 100644 index a2c4953..0000000 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/datagen/provider/tag/ModItemTagsProvider.java +++ /dev/null @@ -1,199 +0,0 @@ -package org.polaris2023.wildwind.hfas.datagen.provider.tag; - -import net.minecraft.core.Holder; -import net.minecraft.core.HolderLookup; -import net.minecraft.core.registries.Registries; -import net.minecraft.data.PackOutput; -import net.minecraft.data.tags.TagAppender; -import net.minecraft.data.tags.TagsProvider; -import net.minecraft.tags.BlockItemTagId; -import net.minecraft.tags.BlockItemTags; -import net.minecraft.tags.ItemTags; -import net.minecraft.tags.TagKey; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.Items; -import net.minecraft.world.level.block.Block; -import net.neoforged.neoforge.common.Tags; -import org.polaris2023.wildwind.hfas.HFASMod; -import org.polaris2023.wildwind.hfas.block.ModBlocks; -import org.polaris2023.wildwind.hfas.tag.ModItemTags; - -import java.util.Arrays; -import java.util.concurrent.CompletableFuture; - -/** - * 物品标签生成器 - * 为木质物品添加原版和模组标签 - *

- * 迁移至26.2时旧有的IntrinsicHolderTagsProvider已被移除。改为父类TagsProvider并由addToTag方法桥接。 - * TODO_FINISHED: 部分item tag key存在缺失问题,已模仿原版行为进行处理,但无法确定这种缺失是否系系统性删除,无法确保对应功能一定可以正常工作。请求测试阶段重点检查。 - * 见[Need Check]注释部分。 - * ——landis, 2026/9/1 - * - * @author baka4n - * @since 2026/04/15 - */ -public class ModItemTagsProvider extends TagsProvider { - - public ModItemTagsProvider(PackOutput output, CompletableFuture lookupProvider) { -// super(output, Registries.ITEM, lookupProvider, item -> item.builtInRegistryHolder().key(), HFASMod.MOD_ID); - super(output, Registries.ITEM, lookupProvider, HFASMod.MOD_ID); - } - - @Override - protected void addTags(HolderLookup.Provider provider) { - // ==================== 焚烬木物品标签 ==================== - registerWoodItemTags( - ModBlocks.BLAZE_LOG.get(), - ModBlocks.BLAZE_WOOD.get(), - ModBlocks.STRIPPED_BLAZE_LOG.get(), - ModBlocks.STRIPPED_BLAZE_WOOD.get(), - ModBlocks.BLAZE_PLANKS.get(), - ModBlocks.BLAZE_STAIRS.get(), - ModBlocks.BLAZE_SLAB.get(), - ModBlocks.BLAZE_FENCE.get(), - ModBlocks.BLAZE_FENCE_GATE.get(), - ModBlocks.BLAZE_DOOR.get(), - ModBlocks.BLAZE_TRAPDOOR.get(), - ModBlocks.BLAZE_PRESSURE_PLATE.get(), - ModBlocks.BLAZE_BUTTON.get(), - ModBlocks.BLAZE_LEAVES.get(), - ModBlocks.BLAZE_SAPLING.get() - ); - - // ==================== 灵焰木物品标签 ==================== - registerWoodItemTags( - ModBlocks.SOUL_LOG.get(), - ModBlocks.SOUL_WOOD.get(), - ModBlocks.STRIPPED_SOUL_LOG.get(), - ModBlocks.STRIPPED_SOUL_WOOD.get(), - ModBlocks.SOUL_PLANKS.get(), - ModBlocks.SOUL_STAIRS.get(), - ModBlocks.SOUL_SLAB.get(), - ModBlocks.SOUL_FENCE.get(), - ModBlocks.SOUL_FENCE_GATE.get(), - ModBlocks.SOUL_DOOR.get(), - ModBlocks.SOUL_TRAPDOOR.get(), - ModBlocks.SOUL_PRESSURE_PLATE.get(), - ModBlocks.SOUL_BUTTON.get(), - ModBlocks.SOUL_LEAVES.get(), - ModBlocks.SOUL_SAPLING.get() - ); - - // ==================== 杜鹃木物品标签 ==================== - registerWoodItemTags( - ModBlocks.AZALEA_LOG.get(), - ModBlocks.AZALEA_WOOD.get(), - ModBlocks.STRIPPED_AZALEA_LOG.get(), - ModBlocks.STRIPPED_AZALEA_WOOD.get(), - ModBlocks.AZALEA_PLANKS.get(), - ModBlocks.AZALEA_STAIRS.get(), - ModBlocks.AZALEA_SLAB.get(), - ModBlocks.AZALEA_FENCE.get(), - ModBlocks.AZALEA_FENCE_GATE.get(), - ModBlocks.AZALEA_DOOR.get(), - ModBlocks.AZALEA_TRAPDOOR.get(), - ModBlocks.AZALEA_PRESSURE_PLATE.get(), - ModBlocks.AZALEA_BUTTON.get(), - null, // 杜鹃木使用原版树叶 - null // 杜鹃木使用原版树苗 - ); - - tag(Tags.Items.ANIMAL_FOODS) - .addTag(ModItemTags.MUDCRAB_FOOD); - addToTag(ModItemTags.MUDCRAB_FOOD, Items.SPIDER_EYE); - } - - /** - * 注册木质物品标签 - */ - private void registerWoodItemTags( - Block log, Block wood, - Block strippedLog, Block strippedWood, - Block planks, Block stairs, Block slab, - Block fence, Block fenceGate, - Block door, Block trapdoor, - Block pressurePlate, Block button, - Block leaves, Block sapling) { - - // 原木物品标签 - addToTag(ItemTags.LOGS, log, wood, strippedLog, strippedWood); -// tag(ItemTags.LOGS) -// .add(log.asItem()) -// .add(wood.asItem()) -// .add(strippedLog.asItem()) -// .add(strippedWood.asItem()); - - // 木板物品标签 - addToTag(ItemTags.PLANKS, planks); - - // 木质楼梯物品标签 - addToTag(ItemTags.WOODEN_STAIRS,stairs); - - // 木质台阶物品标签 - addToTag(ItemTags.WOODEN_SLABS, slab); - - // 木质栅栏物品标签 - addToTag(Tags.Items.FENCES_WOODEN, fence); - - // 栅栏物品标签 - // 栅栏tag默认包含"#c:fences/wooden",弃用 -// tag(Tags.Items.FENCES) -// .add(fence.asItem()); - - // 木质栅栏门物品标签 - addToTag(Tags.Items.FENCE_GATES_WOODEN, fenceGate); - - // 栅栏门物品标签 - addToTag(ItemTags.FENCE_GATES, fenceGate); - - // 木质门物品标签 - addToTag(ItemTags.WOODEN_DOORS,door); - - // 门物品标签 - // bugjump不知道给这玩意更新到哪去了 item没key 难绷 - // [NeedCheck] - addToTag(BlockItemTags.DOORS.item(), door); - - // 活板门物品标签 - // 续上:我要点名某些明明有包含关系但是就是不引用子tag还要把key删掉的tag - // [NeedCheck] - addToTag(BlockItemTags.TRAPDOORS.item(), trapdoor); - - // 木质活板门物品标签 - addToTag(ItemTags.WOODEN_TRAPDOORS, trapdoor); - - // 木质压力板物品标签 - addToTag(ItemTags.WOODEN_PRESSURE_PLATES, pressurePlate); - - // 木质按钮物品标签 - addToTag(ItemTags.WOODEN_BUTTONS, button); - - // 按钮物品标签 - // 不是哥们 你怎么也没了我朝为 - // [NeedCheck] - addToTag(BlockItemTags.BUTTONS.item(), button); - - // 树叶物品标签 - if (leaves != null) { - addToTag(ItemTags.LEAVES, leaves); - } - - // 树苗物品标签 - if (sapling != null) { - addToTag(ItemTags.SAPLINGS, sapling); - } - } - - @SuppressWarnings("all") - public void addToTag(TagKey tag, Block... items){ - if(items.length == 0) return; - tag(tag).addAll(Arrays.stream(items).map(Block::asItem).map(Item::builtInRegistryHolder).map(Holder.Reference::getKey)); - } - - @SuppressWarnings("all") - public void addToTag(TagKey tag, Item... items){ - if(items.length == 0) return; - tag(tag).addAll(Arrays.stream(items).map(Item::builtInRegistryHolder).map(Holder.Reference::getKey)); - } -} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/event/EntitiesHandler.java b/src/hfas/java/org/polaris2023/wildwind/hfas/event/EntitiesHandler.java deleted file mode 100644 index 7d1db27..0000000 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/event/EntitiesHandler.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.polaris2023.wildwind.hfas.event; - -import net.minecraft.world.level.levelgen.Heightmap; -import net.neoforged.bus.api.SubscribeEvent; -import net.neoforged.fml.common.EventBusSubscriber; -import net.neoforged.neoforge.event.entity.EntityAttributeCreationEvent; -import net.neoforged.neoforge.event.entity.RegisterSpawnPlacementsEvent; -import org.polaris2023.wildwind.hfas.entity.animal.Mudcrab; -import org.polaris2023.wildwind.hfas.registry.ModEntities; - -@EventBusSubscriber -public class EntitiesHandler { - @SubscribeEvent - static void onAttributeCreate(EntityAttributeCreationEvent event) { - event.put(ModEntities.MUDCRAB.get(), Mudcrab.createAttributes().build()); - } - - @SubscribeEvent - static void registerSpawnPlacements(RegisterSpawnPlacementsEvent event) { - event.register(ModEntities.MUDCRAB.get(), Mudcrab.SPAWN_PLACEMENT, Heightmap.Types.OCEAN_FLOOR, Mudcrab::checkMudcrabInWaterGroundSpawnRules, RegisterSpawnPlacementsEvent.Operation.REPLACE); - event.register(ModEntities.MUDCRAB.get(), Mudcrab::checkMudcrabOnGroundSpawnRules); - } -} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/event/FletchingTableReplaceHandler.java b/src/hfas/java/org/polaris2023/wildwind/hfas/event/FletchingTableReplaceHandler.java deleted file mode 100644 index b397c17..0000000 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/event/FletchingTableReplaceHandler.java +++ /dev/null @@ -1,87 +0,0 @@ -package org.polaris2023.wildwind.hfas.event; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.properties.Property; -import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraft.world.phys.AABB; -import net.neoforged.bus.api.EventPriority; -import net.neoforged.bus.api.SubscribeEvent; -import net.neoforged.fml.common.EventBusSubscriber; -import net.neoforged.neoforge.event.level.BlockEvent; -import net.neoforged.neoforge.event.level.ChunkDataEvent; -import net.neoforged.neoforge.event.level.ChunkEvent; -import org.polaris2023.wildwind.hfas.HFASMod; -import org.polaris2023.wildwind.hfas.block.ModBlocks; -import org.polaris2023.wildwind.hfas.config.ModCommonConfig; - -/** - * 世界生成事件处理器 - * 用于替换结构内的原版制箭台为模组制箭台 - * - * @author baka4n - * @since 2026/04/15 - */ -@EventBusSubscriber(modid = HFASMod.MOD_ID) -public class FletchingTableReplaceHandler { - - /** - * 方块放置事件 - 处理所有制箭台放置 - * 包括结构生成、玩家放置等 - */ - @SubscribeEvent(priority = EventPriority.HIGHEST) - public static void onBlockPlace(BlockEvent.EntityPlaceEvent event) { - if (!ModCommonConfig.shouldReplaceVanillaFletchingTable()) { - return; - } - - BlockState placedState = event.getPlacedBlock(); - - if (placedState.getBlock() == Blocks.FLETCHING_TABLE) { - LevelAccessor levelAccessor = event.getLevel(); - - if (levelAccessor instanceof Level level && !level.isClientSide()) { - BlockPos pos = event.getPos(); - // 取消原事件并设置模组制箭台 - event.setCanceled(true); - level.setBlock(pos, ModBlocks.FLETCHING_TABLE.get().defaultBlockState(), 3); - } - } - } - - /** - * 区块加载事件 - 替换区块内的原版制箭台 - */ - @SuppressWarnings({"unchecked", "rawtypes"}) - @SubscribeEvent(priority = EventPriority.HIGHEST) - public static void onChunkLoad(ChunkEvent.Load event) { - if (!ModCommonConfig.shouldReplaceVanillaFletchingTable()) { - return; - } - - LevelChunk chunk = event.getChunk(); - LevelAccessor level = event.getLevel(); - - if (!level.isClientSide()) { - BlockPos.betweenClosedStream(new AABB( - chunk.getPos().getMinBlockX(), level.getMinY(), chunk.getPos().getMinBlockZ(), - chunk.getPos().getMaxBlockX(), 200, chunk.getPos().getMaxBlockZ() - )).forEach(pos -> { - BlockState state = chunk.getBlockState(pos); - if (state.is(Blocks.FLETCHING_TABLE)) { - BlockState returnState = ModBlocks.FLETCHING_TABLE.get().defaultBlockState(); - state.getValues().forEach(v -> { - Property property = v.property(); - Comparable value = v.value(); - returnState.setValue(property, value); - }); - chunk.setBlockState(pos, returnState); - } - }); - - } - } -} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/event/FuelHandler.java b/src/hfas/java/org/polaris2023/wildwind/hfas/event/FuelHandler.java deleted file mode 100644 index d72eacb..0000000 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/event/FuelHandler.java +++ /dev/null @@ -1,83 +0,0 @@ -package org.polaris2023.wildwind.hfas.event; - -import net.minecraft.world.item.Item; -import net.minecraft.world.level.block.Block; -import net.neoforged.bus.api.SubscribeEvent; -import net.neoforged.fml.common.EventBusSubscriber; -import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent; -import net.neoforged.neoforge.event.furnace.FurnaceFuelBurnTimeEvent; -import org.polaris2023.wildwind.hfas.HFASMod; -import org.polaris2023.wildwind.hfas.block.ModBlocks; - -/** - * 燃料事件处理器 - * 为木质方块添加燃料功能 - * - * @author baka4n - * @since 2026/04/15 - */ -@EventBusSubscriber(modid = HFASMod.MOD_ID) -public class FuelHandler { - - /** - * 燃料燃烧时间事件 - * 木质方块可作为燃料,燃烧300 tick(与原版木板相同) - */ - @SubscribeEvent - public static void onFuelBurnTime(FurnaceFuelBurnTimeEvent event) { - Item item = event.getItemStack().getItem(); - - // 检查是否是木质方块物品 - int burnTime = getWoodBurnTime(item); - if (burnTime > 0) { - event.setBurnTime(burnTime); - } - } - - /** - * 获取木质方块的燃烧时间 - */ - private static int getWoodBurnTime(Item item) { - // 焚烬木 - 300 tick(15秒) - if (isBlazeWoodItem(item)) return 300; - // 灵焰木 - 300 tick - if (isSoulWoodItem(item)) return 300; - // 杜鹃木 - 300 tick - if (isAzaleaWoodItem(item)) return 300; - - return 0; - } - - private static boolean isBlazeWoodItem(Item item) { - return item == ModBlocks.BLAZE_LOG.get().asItem() - || item == ModBlocks.BLAZE_WOOD.get().asItem() - || item == ModBlocks.STRIPPED_BLAZE_LOG.get().asItem() - || item == ModBlocks.STRIPPED_BLAZE_WOOD.get().asItem() - || item == ModBlocks.BLAZE_PLANKS.get().asItem() - || item == ModBlocks.BLAZE_SLAB.get().asItem() - || item == ModBlocks.BLAZE_FENCE.get().asItem() - || item == ModBlocks.BLAZE_FENCE_GATE.get().asItem(); - } - - private static boolean isSoulWoodItem(Item item) { - return item == ModBlocks.SOUL_LOG.get().asItem() - || item == ModBlocks.SOUL_WOOD.get().asItem() - || item == ModBlocks.STRIPPED_SOUL_LOG.get().asItem() - || item == ModBlocks.STRIPPED_SOUL_WOOD.get().asItem() - || item == ModBlocks.SOUL_PLANKS.get().asItem() - || item == ModBlocks.SOUL_SLAB.get().asItem() - || item == ModBlocks.SOUL_FENCE.get().asItem() - || item == ModBlocks.SOUL_FENCE_GATE.get().asItem(); - } - - private static boolean isAzaleaWoodItem(Item item) { - return item == ModBlocks.AZALEA_LOG.get().asItem() - || item == ModBlocks.AZALEA_WOOD.get().asItem() - || item == ModBlocks.STRIPPED_AZALEA_LOG.get().asItem() - || item == ModBlocks.STRIPPED_AZALEA_WOOD.get().asItem() - || item == ModBlocks.AZALEA_PLANKS.get().asItem() - || item == ModBlocks.AZALEA_SLAB.get().asItem() - || item == ModBlocks.AZALEA_FENCE.get().asItem() - || item == ModBlocks.AZALEA_FENCE_GATE.get().asItem(); - } -} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/groups/ModCreativeTabs.java b/src/hfas/java/org/polaris2023/wildwind/hfas/groups/ModCreativeTabs.java deleted file mode 100644 index ac957bb..0000000 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/groups/ModCreativeTabs.java +++ /dev/null @@ -1,136 +0,0 @@ -package org.polaris2023.wildwind.hfas.groups; - -import net.minecraft.world.item.CreativeModeTab; -import net.minecraft.world.item.CreativeModeTabs; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.Items; -import net.minecraft.world.level.block.Blocks; -import net.neoforged.bus.api.SubscribeEvent; -import net.neoforged.fml.common.EventBusSubscriber; -import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent; -import org.polaris2023.wildwind.hfas.HFASMod; -import org.polaris2023.wildwind.hfas.block.ModBlocks; - -/** - * 创造模式物品栏配置 - * 将模组物品放入原版创造模式物品栏并排序 - * - * @author baka4n - * @since 2026/04/15 - */ -//TODO 考虑统一迁移至registry下,同时考虑合入自定义tab -@EventBusSubscriber(modid = HFASMod.MOD_ID) -public class ModCreativeTabs { - - @SubscribeEvent - public static void buildCreativeTabContents(BuildCreativeModeTabContentsEvent event) { - // 建筑方块物品栏 - - if (event.getTabKey() == CreativeModeTabs.BUILDING_BLOCKS) { - // 杜鹃系列 - { - ItemStack logStack = ModBlocks.AZALEA_LOG.toStack(); - event.insertAfter(new ItemStack(Blocks.CHERRY_BUTTON), logStack, CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); - ItemStack woodStack = ModBlocks.AZALEA_WOOD.toStack(); - event.insertAfter(logStack, woodStack, CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); - ItemStack strippedLogStack = ModBlocks.STRIPPED_AZALEA_LOG.toStack(); - event.insertAfter(woodStack, strippedLogStack, CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); - ItemStack strippedWoodStack = ModBlocks.STRIPPED_AZALEA_WOOD.toStack(); - event.insertAfter(strippedLogStack, strippedWoodStack, CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); - ItemStack planksStack = ModBlocks.AZALEA_PLANKS.toStack(); - event.insertAfter(strippedWoodStack, planksStack, CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); - ItemStack stairsStack = ModBlocks.AZALEA_STAIRS.toStack(); - event.insertAfter(planksStack, stairsStack, CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); - ItemStack slabStack = ModBlocks.AZALEA_SLAB.toStack(); - event.insertAfter(stairsStack, slabStack, CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); - ItemStack fenceStack = ModBlocks.AZALEA_FENCE.toStack(); - event.insertAfter(slabStack, fenceStack, CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); - ItemStack fenceGateStack = ModBlocks.AZALEA_FENCE_GATE.toStack(); - event.insertAfter(fenceStack, fenceGateStack, CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); - ItemStack doorStack = ModBlocks.AZALEA_DOOR.toStack(); - event.insertAfter(fenceGateStack, doorStack, CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); - ItemStack trapdoorStack = ModBlocks.AZALEA_TRAPDOOR.toStack(); - event.insertAfter(doorStack, trapdoorStack, CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); - event.insertAfter(trapdoorStack, ModBlocks.AZALEA_PRESSURE_PLATE.toStack(), CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); - } - // 焚烬系列 - { - ItemStack logStack = ModBlocks.BLAZE_LOG.toStack(); - event.insertAfter(new ItemStack(Blocks.BAMBOO_BUTTON), logStack, CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); - ItemStack woodStack = ModBlocks.BLAZE_WOOD.toStack(); - event.insertAfter(logStack, woodStack, CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); - ItemStack strippedLogStack = ModBlocks.STRIPPED_BLAZE_LOG.toStack(); - event.insertAfter(woodStack, strippedLogStack, CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); - ItemStack strippedWoodStack = ModBlocks.STRIPPED_BLAZE_WOOD.toStack(); - event.insertAfter(strippedLogStack, strippedWoodStack, CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); - ItemStack planksStack = ModBlocks.BLAZE_PLANKS.toStack(); - event.insertAfter(strippedWoodStack, planksStack, CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); - ItemStack stairsStack = ModBlocks.BLAZE_STAIRS.toStack(); - event.insertAfter(planksStack, stairsStack, CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); - ItemStack slabStack = ModBlocks.BLAZE_SLAB.toStack(); - event.insertAfter(stairsStack, slabStack, CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); - ItemStack fenceStack = ModBlocks.BLAZE_FENCE.toStack(); - event.insertAfter(slabStack, fenceStack, CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); - ItemStack fenceGateStack = ModBlocks.BLAZE_FENCE_GATE.toStack(); - event.insertAfter(fenceStack, fenceGateStack, CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); - ItemStack doorStack = ModBlocks.BLAZE_DOOR.toStack(); - event.insertAfter(fenceGateStack, doorStack, CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); - ItemStack trapdoorStack = ModBlocks.BLAZE_TRAPDOOR.toStack(); - event.insertAfter(doorStack, trapdoorStack, CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); - event.insertAfter(trapdoorStack, ModBlocks.BLAZE_PRESSURE_PLATE.toStack(), CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); - } - // 灵焰系列 - { - ItemStack logStack = ModBlocks.SOUL_LOG.toStack(); - event.insertAfter(ModBlocks.BLAZE_PRESSURE_PLATE.toStack(), logStack, CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); - ItemStack woodStack = ModBlocks.SOUL_WOOD.toStack(); - event.insertAfter(logStack, woodStack, CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); - ItemStack strippedLogStack = ModBlocks.STRIPPED_SOUL_LOG.toStack(); - event.insertAfter(woodStack, strippedLogStack, CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); - ItemStack strippedWoodStack = ModBlocks.STRIPPED_SOUL_WOOD.toStack(); - event.insertAfter(strippedLogStack, strippedWoodStack, CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); - ItemStack planksStack = ModBlocks.SOUL_PLANKS.toStack(); - event.insertAfter(strippedWoodStack, planksStack, CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); - ItemStack stairsStack = ModBlocks.SOUL_STAIRS.toStack(); - event.insertAfter(planksStack, stairsStack, CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); - ItemStack slabStack = ModBlocks.SOUL_SLAB.toStack(); - event.insertAfter(stairsStack, slabStack, CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); - ItemStack fenceStack = ModBlocks.SOUL_FENCE.toStack(); - event.insertAfter(slabStack, fenceStack, CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); - ItemStack fenceGateStack = ModBlocks.SOUL_FENCE_GATE.toStack(); - event.insertAfter(fenceStack, fenceGateStack, CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); - ItemStack doorStack = ModBlocks.SOUL_DOOR.toStack(); - event.insertAfter(fenceGateStack, doorStack, CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); - ItemStack trapdoorStack = ModBlocks.SOUL_TRAPDOOR.toStack(); - event.insertAfter(doorStack, trapdoorStack, CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); - event.insertAfter(trapdoorStack, ModBlocks.SOUL_PRESSURE_PLATE.toStack(), CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); - } - - - // 焦灰草方块 -// event.accept(ModBlocks.SCORCHED_GRASS_BLOCK.get()); -// // 焦土 -// event.accept(ModBlocks.SCORCHED_DIRT.get()); - } - - // 自然方块物品栏 - if (event.getTabKey() == CreativeModeTabs.NATURAL_BLOCKS) { - ItemStack azaleaLogStack = ModBlocks.AZALEA_LOG.toStack(); - event.insertAfter(new ItemStack(Items.CHERRY_LOG), azaleaLogStack, CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); - ItemStack blazeLogStack = ModBlocks.BLAZE_LOG.toStack(); - event.insertAfter(azaleaLogStack, blazeLogStack, CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); - event.insertAfter(blazeLogStack, ModBlocks.SOUL_LOG.toStack(), CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); - // 焦灰草丛 -// event.accept(ModBlocks.SCORCHED_GRASS.get()); -// // 焦灰枝条 -// event.accept(ModBlocks.SCORCHED_TWIG.get()); -// // 仙人球 -// event.accept(ModBlocks.TINY_CACTUS.get()); -// // 焦灰草方块 -// event.accept(ModBlocks.SCORCHED_GRASS_BLOCK.get()); -// // 焦土 -// event.accept(ModBlocks.SCORCHED_DIRT.get()); - } - - } -} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/menu/FletchingTableMenu.java b/src/hfas/java/org/polaris2023/wildwind/hfas/menu/FletchingTableMenu.java deleted file mode 100644 index 29f4e81..0000000 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/menu/FletchingTableMenu.java +++ /dev/null @@ -1,128 +0,0 @@ -package org.polaris2023.wildwind.hfas.menu; - -import net.minecraft.world.Container; -import net.minecraft.world.SimpleContainer; -import net.minecraft.world.entity.player.Inventory; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.inventory.AbstractContainerMenu; -import net.minecraft.world.inventory.ContainerLevelAccess; -import net.minecraft.world.inventory.Slot; -import net.minecraft.world.item.ItemStack; -import org.polaris2023.wildwind.hfas.block.ModBlocks; -import org.polaris2023.wildwind.hfas.block.entity.FletchingTableBlockEntity; - -import javax.annotation.Nullable; -import java.util.Optional; - -/** - * 制箭台菜单 - * - * @author baka4n - * @since 2026/04/15 - */ -public class FletchingTableMenu extends AbstractContainerMenu { - private final Container container; - private final ContainerLevelAccess access; - - public FletchingTableMenu(int containerId, Inventory playerInventory) { - this(containerId, playerInventory, new SimpleContainer(4), ContainerLevelAccess.NULL); - } - - public FletchingTableMenu(int containerId, Inventory playerInventory, Container container, ContainerLevelAccess access) { - super(ModMenus.FLETCHING_TABLE.get(), containerId); - this.container = container; - this.access = access; - - // 箭羽槽 (slot 0) - this.addSlot(FletchingTableBlockEntity.Slots.SLOT_FLETCHING.toSlot(container, 26, 18)); - // 箭杆槽 (slot 1) - this.addSlot(FletchingTableBlockEntity.Slots.SLOT_SHAFT.toSlot(container, 62, 18)); - // 箭头槽 (slot 2) - this.addSlot( FletchingTableBlockEntity.Slots.SLOT_HEAD.toSlot(container, 98, 18)); - // 燃料槽口(slot 3) - this.addSlot(FletchingTableBlockEntity.Slots.SLOT_FUEL.toSlot(container, 62, 68)); - // 输出槽 (slot 4) - this.addSlot(this.addSlot(FletchingTableBlockEntity.Slots.SLOT_RESULT.toSlot(container, 134, 18))); - - // 添加玩家物品栏 - for (int row = 0; row < 3; ++row) { - for (int col = 0; col < 9; ++col) { - this.addSlot(new Slot(playerInventory, col + row * 9 + 9, 8 + col * 18, 50 + row * 18)); - } - } - - // 添加玩家快捷栏 - for (int col = 0; col < 9; ++col) { - this.addSlot(new Slot(playerInventory, col, 8 + col * 18, 108)); - } - } - - /** - * 输出槽 - 不能放入物品,取出时消耗材料 - */ - private class ResultSlot extends Slot { - public ResultSlot(Container container, int slot, int x, int y) { - super(container, slot, x, y); - } - - @Override - public boolean mayPlace(ItemStack stack) { - return false; - } - - @Override - public void onTake(Player player, ItemStack stack) { - // 消耗输入材料 -// container.removeItem(FletchingTableBlockEntity.SLOT_FLETCHING, 1); -// container.removeItem(FletchingTableBlockEntity.SLOT_SHAFT, 1); -// container.removeItem(FletchingTableBlockEntity.SLOT_HEAD, 1); - super.onTake(player, stack); - } - } - - @Override - public ItemStack quickMoveStack(Player player, int index) { - ItemStack itemStack = ItemStack.EMPTY; - Slot slot = this.slots.get(index); - - if (slot != null && slot.hasItem()) { - ItemStack slotItem = slot.getItem(); - itemStack = slotItem.copy(); - - // 输出槽 (index 3) - if (index == 3) { - if (!this.moveItemStackTo(slotItem, 4, this.slots.size(), true)) { - return ItemStack.EMPTY; - } - slot.onTake(player, slotItem); - } - // 输入槽 (index 0-2) - else if (index >= 0 && index < 3) { - if (!this.moveItemStackTo(slotItem, 4, this.slots.size(), true)) { - return ItemStack.EMPTY; - } - } - // 玩家物品栏 - else { - // 尝试放入输入槽 - if (!this.moveItemStackTo(slotItem, 0, 3, false)) { - return ItemStack.EMPTY; - } - } - - if (slotItem.isEmpty()) { - slot.set(ItemStack.EMPTY); - } else { - slot.setChanged(); - } - } - - return itemStack; - } - - @Override - public boolean stillValid(Player player) { - return stillValid(this.access, player, ModBlocks.FLETCHING_TABLE.get()); - } - -} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/registry/ModCreativeTabs.java b/src/hfas/java/org/polaris2023/wildwind/hfas/registry/ModCreativeTabs.java deleted file mode 100644 index a89ef9d..0000000 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/registry/ModCreativeTabs.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.polaris2023.wildwind.hfas.registry; - -import net.minecraft.core.registries.Registries; -import net.minecraft.network.chat.Component; -import net.minecraft.world.item.CreativeModeTab; -import net.neoforged.bus.api.IEventBus; -import net.neoforged.neoforge.registries.DeferredHolder; -import net.neoforged.neoforge.registries.DeferredRegister; -import org.polaris2023.wildwind.hfas.HFASMod; - -public class ModCreativeTabs { - public static final DeferredRegister CREATIVE_TABS = - DeferredRegister.create(Registries.CREATIVE_MODE_TAB, HFASMod.MOD_ID); - /** - * 模组专用创造模式物品栏喵~ - */ - public static final DeferredHolder WILD_WIND = - CREATIVE_TABS.register("wild_wind", () -> CreativeModeTab.builder() - .title(Component.translatable("mod.wild_wind.name")) -// .icon(() -> ModItems.CINDER.log().get().getDefaultInstance()) TODO 换成对应的物品 - .icon(() -> ModItems.MUDCRAB_BUCKET.get().getDefaultInstance()) - .displayItems((params, output) -> addStacks(output)) - .build() - ); - - /** - * 向模组事件总线注册创造模式物品栏喵~ - * - * @param modBus 模组事件总线喵~ - */ - public static void register(IEventBus modBus) { - CREATIVE_TABS.register(modBus); - } - - private static void addStacks(CreativeModeTab.Output output){ - output.accept(ModItems.MUDCRAB_BUCKET); - output.accept(ModItems.MUDCRAB_SPAWN_EGG); - output.accept(ModItems.CRAB_CLAW); - output.accept(ModItems.OMNI_CLAW); - } -} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/registry/ModEntities.java b/src/hfas/java/org/polaris2023/wildwind/hfas/registry/ModEntities.java deleted file mode 100644 index 1f08a6c..0000000 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/registry/ModEntities.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.polaris2023.wildwind.hfas.registry; - -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.MobCategory; -import net.neoforged.bus.api.IEventBus; -import net.neoforged.neoforge.registries.DeferredHolder; -import net.neoforged.neoforge.registries.DeferredRegister; -import org.polaris2023.wildwind.hfas.HFASMod; -import org.polaris2023.wildwind.hfas.client.eventsub.EntitiesClientHandler; -import org.polaris2023.wildwind.hfas.entity.animal.Mudcrab; - - -public class ModEntities { - public static final DeferredRegister.Entities ENTITY_TYPES = - DeferredRegister.createEntities(HFASMod.MOD_ID); - - private ModEntities() { - } - - //泥沼蟹实体类型 - public static final DeferredHolder, EntityType> MUDCRAB = - ENTITY_TYPES.registerEntityType("mudcrab", Mudcrab::new, MobCategory.WATER_CREATURE, - builder -> builder.sized(0.5F, 0.55F).clientTrackingRange(8) - ); - - /** - * 向模组事件总线注册实体类型喵~ - * - * @see EntitiesClientHandler EntitiesClientEvent 实体客户端渲染绑定 - * @see org.polaris2023.wildwind.hfas.event.EntitiesHandler EntitiesHandler 实体服务端信息(attribute等绑定) - * - * @param modBus 模组事件总线喵~ - */ - public static void register(IEventBus modBus) { - ENTITY_TYPES.register(modBus); - } - -} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/worldgen/ModTreeGrowers.java b/src/hfas/java/org/polaris2023/wildwind/hfas/worldgen/ModTreeGrowers.java deleted file mode 100644 index 034c406..0000000 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/worldgen/ModTreeGrowers.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.polaris2023.wildwind.hfas.worldgen; - -import net.minecraft.resources.ResourceKey; -import net.minecraft.world.level.block.grower.TreeGrower; -import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; -import org.polaris2023.wildwind.hfas.HFASMod; - -import java.util.Optional; - -/** - * 树木生长器注册 - * - * @author baka4n - * @since 2026/04/15 - */ -public class ModTreeGrowers { - - // 焚烬木树苗生长器 - public static final TreeGrower BLAZE = new TreeGrower( - "blaze", - Optional.empty(), - Optional.of(ModConfiguredFeatures.BLAZE_TREE_KEY), - Optional.empty() - ); - - // 灵焰木树苗生长器 - public static final TreeGrower SOUL = new TreeGrower( - "soul", - Optional.empty(), - Optional.of(ModConfiguredFeatures.SOUL_TREE_KEY), - Optional.empty() - ); - - // 杜鹃木树苗生长器 - public static final TreeGrower AZALEA = new TreeGrower( - "azalea", - Optional.empty(), - Optional.of(ModConfiguredFeatures.AZALEA_TREE_KEY), - Optional.empty() - ); -} diff --git a/src/hfas/resources/ww_hfas.mixins.json b/src/hfas/resources/ww_hfas.mixins.json deleted file mode 100644 index 13489e6..0000000 --- a/src/hfas/resources/ww_hfas.mixins.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "required": true, - "package": "org.polaris2023.wildwind.hfas.mixin", - "compatibilityLevel": "JAVA_25", - "mixins": [ - "AzaleaBlockMixin", - "EnchantmentHelperMixin", - "ItemStackMixin", - "MobMixin", - "PlayerMixin", - "ServerPlayerGameModeMixin" - ], - "injectors": { - "defaultRequire": 1 - }, - "overwrites": { - "requireAnnotations": true - } -} diff --git a/src/smoke/java/org/polaris2023/wildwind/smoke/ClientInstallationTests.java b/src/smoke/java/org/polaris2023/wildwind/smoke/ClientInstallationTests.java new file mode 100644 index 0000000..42ad522 --- /dev/null +++ b/src/smoke/java/org/polaris2023/wildwind/smoke/ClientInstallationTests.java @@ -0,0 +1,47 @@ +package org.polaris2023.wildwind.smoke; + +import com.mojang.logging.LogUtils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screens.TitleScreen; +import net.minecraft.resources.Identifier; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.ModList; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.client.event.ClientTickEvent; + +/** Opt-in client resource-load check; never packaged in a release mod. */ +@EventBusSubscriber(modid = "wild_wind_smoke", value = Dist.CLIENT) +public final class ClientInstallationTests { + @SubscribeEvent + public static void tick(ClientTickEvent.Post event) { + if (!Boolean.getBoolean("wildwind.clientSmoke")) return; + var client = Minecraft.getInstance(); + if (client.gui.overlay() != null || !(client.gui.screen() instanceof TitleScreen)) return; + require(client, "wild_wind_core:textures/entity/signs/azalea.png"); + // Verify conservative server pagination against the actual loaded Minecraft font. + var pages = org.polaris2023.wildwind.core.inspection.BookPages.paginate(java.util.List.of( + "原野之风·属性记录", "物品ID:wild_wind_wilderness:muddy_pig_spawn_egg", + "活塞推动行为:不可推动,不可拉动", "烧炼时间:15秒(300刻)", "空气阻力修正系数:0.01")); + for (var page : pages) { + if (client.font.wordWrapHeight(net.minecraft.network.chat.Component.literal(page), 114) > 126) throw new IllegalStateException("Inspector page exceeds book height"); + for (var line : page.split("\n")) { + if (client.font.width(line) > 114) throw new IllegalStateException("Inspector line exceeds book width: " + line); + } + } + if (ModList.get().isLoaded("wild_wind_wilderness")) { + require(client, "wild_wind_wilderness:textures/entity/pig/pig_muddy.png"); + require(client, "wild_wind_wilderness:textures/entity/pig/pig_muddy_baby.png"); + require(client, "wild_wind_wilderness:textures/entity/piranha.png"); + require(client, "wild_wind_wilderness:geckolib/models/entity/mudcrab.geo.json"); + } + LogUtils.getLogger().info("Wild Wind client installation check passed"); + client.stop(); + } + + private static void require(Minecraft client, String id) { + if (client.getResourceManager().getResource(Identifier.parse(id)).isEmpty()) { + throw new IllegalStateException("Missing module resource: " + id); + } + } +} diff --git a/src/smoke/java/org/polaris2023/wildwind/smoke/InstallationTests.java b/src/smoke/java/org/polaris2023/wildwind/smoke/InstallationTests.java new file mode 100644 index 0000000..c0fd676 --- /dev/null +++ b/src/smoke/java/org/polaris2023/wildwind/smoke/InstallationTests.java @@ -0,0 +1,61 @@ +package org.polaris2023.wildwind.smoke; + +import java.util.Arrays; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.registries.Registries; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.Identifier; +import net.minecraft.world.item.CreativeModeTab; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.fml.ModList; +import net.neoforged.fml.common.Mod; +import net.neoforged.neoforge.registries.DeferredRegister; +import org.polaris2023.wildwind.core.registry.ModCreativeTabs; + +/** Boots each supported installation using its actual release JAR dependencies. */ +@Mod("wild_wind_smoke") +public final class InstallationTests { + public InstallationTests(IEventBus bus) { + var functions = DeferredRegister.>create(Registries.TEST_FUNCTION, "wild_wind_smoke"); + functions.register("installation", () -> InstallationTests::installation); + functions.register(bus); + } + + private static void check(GameTestHelper h, boolean condition, String message) { + h.assertTrue(condition, Component.literal(message)); + } + + private static void installation(GameTestHelper h) { + Set expected = Arrays.stream(System.getProperty("wildwind.testModules").split(",")).collect(Collectors.toSet()); + for (String module : new String[]{"core", "wilderness", "barren"}) { + check(h, ModList.get().isLoaded("wild_wind_" + module) == expected.contains(module), "Loaded module: " + module); + } + check(h, ModList.get().isLoaded("geckolib") == expected.contains("wilderness"), "Only Wilderness needs GeckoLib"); + check(h, !ModList.get().isLoaded("ww_hfas") && !ModList.get().isLoaded("ww_structures"), "Legacy entrypoints must not load"); + var tab = ModCreativeTabs.WILD_WIND.get(); + tab.buildContents(new CreativeModeTab.ItemDisplayParameters(h.getLevel().enabledFeatures(), true, h.getLevel().registryAccess())); + for (String path : new String[]{"azalea_planks", "azalea_sign", "azalea_hanging_sign", "azalea_shelf", "kiln", "duckweed"}) { + check(h, tab.contains(BuiltInRegistries.ITEM.getValue(Identifier.parse("wild_wind_core:" + path)).getDefaultInstance()), "Core item in tab: " + path); + } + for (String path : new String[]{"blaze_planks", "soul_planks", "scorched_dirt", "muddy_pig_spawn_egg"}) { + var id = Identifier.parse("wild_wind_wilderness:" + path); + check(h, BuiltInRegistries.ITEM.containsKey(id) == expected.contains("wilderness"), "Wilderness ownership: " + path); + if (expected.contains("wilderness")) check(h, tab.contains(BuiltInRegistries.ITEM.getValue(id).getDefaultInstance()), "Wilderness tab entry: " + path); + } + check(h, BuiltInRegistries.BLOCK.containsKey(Identifier.parse("wild_wind_barren:tiny_cactus")) == expected.contains("barren"), "Cactus belongs only to Barren"); + check(h, BuiltInRegistries.BLOCK.keySet().stream().noneMatch(id -> id.getNamespace().startsWith("wild_wind_") && id.getPath().equals("fletching_table")), "Custom fletching table removed"); + var inspectionPos = h.absolutePos(new net.minecraft.core.BlockPos(2, 2, 2)); + h.getLevel().setBlockAndUpdate(inspectionPos, net.minecraft.world.level.block.Blocks.OAK_PLANKS.defaultBlockState()); + var report = org.polaris2023.wildwind.core.inspection.InspectionReport.block(h.getLevel(), inspectionPos); + check(h, report.contains("可再生:是") && report.contains("硫方怪原型:弹性(橡胶球)"), "Inspector works with only Core and its own tags"); + var book = new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.WRITABLE_BOOK); + var signed = org.polaris2023.wildwind.core.inspection.BookInspectionHandler.sign(book, + org.polaris2023.wildwind.core.inspection.BookPages.paginate(report), Component.literal("Oak Planks(minecraft:oak_planks)"), "test"); + check(h, signed.is(net.minecraft.world.item.Items.WRITTEN_BOOK), "Core can persist complete signed inspection report"); + h.succeed(); + } +} diff --git a/src/smoke/resources/data/wild_wind_smoke/structure/empty.nbt b/src/smoke/resources/data/wild_wind_smoke/structure/empty.nbt new file mode 100644 index 0000000..1b63d36 Binary files /dev/null and b/src/smoke/resources/data/wild_wind_smoke/structure/empty.nbt differ diff --git a/src/smoke/resources/data/wild_wind_smoke/test_instance/installation.json b/src/smoke/resources/data/wild_wind_smoke/test_instance/installation.json new file mode 100644 index 0000000..182f139 --- /dev/null +++ b/src/smoke/resources/data/wild_wind_smoke/test_instance/installation.json @@ -0,0 +1,7 @@ +{ + "type": "minecraft:function", + "function": "wild_wind_smoke:installation", + "environment": "minecraft:default", + "structure": "wild_wind_smoke:empty", + "max_ticks": 100 +} \ No newline at end of file diff --git a/src/templates/META-INF/neoforge.mods.toml b/src/templates/META-INF/neoforge.mods.toml index 7986c64..5efef7e 100644 --- a/src/templates/META-INF/neoforge.mods.toml +++ b/src/templates/META-INF/neoforge.mods.toml @@ -1,96 +1,37 @@ -# This is an example neoforge.mods.toml file. It contains the data relating to the loading mods. -# There are several mandatory fields (#mandatory), and many more that are optional (#optional). -# The overall format is standard TOML format, v0.5.0. -# Note that there are a couple of TOML lists in this file. -# Find more information on toml format here: https://github.com/toml-lang/toml - -# The license for you mod. This is mandatory metadata and allows for easier comprehension of your redistributive properties. -# Review your options at https://choosealicense.com/. All rights reserved is the default copyright stance, and is thus the default here. license="${mod_license}" - -# A URL to refer people to when problems occur with this mod -#issueTrackerURL="https://change.me.to.your.issue.tracker.example.invalid/" #optional - -# A list of mods - how many allowed here is determined by the individual mod loader -[[mods]] #mandatory - -# The modid of the mod -modId="${mod_id}" #mandatory - -# The version number of the mod -version="${mod_version}" #mandatory - -# A display name for the mod -displayName="${mod_name}" #mandatory - -# A URL to query for updates for this mod. See the JSON update specification https://docs.neoforged.net/docs/misc/updatechecker/ -#updateJSONURL="https://change.me.example.invalid/updates.json" #optional - -# A URL for the "homepage" for this mod, displayed in the mod UI -#displayURL="https://change.me.to.your.mods.homepage.example.invalid/" #optional - -# A file name (in the root of the mod JAR) containing a logo for display -#logoFile="examplemod.png" #optional - -# A text field displayed in the mod UI -#credits="" #optional - -# The authors of the mod, displayed in the mod UI (optional) +[[mods]] +modId="${mod_id}" +version="${mod_version}" +displayName="${mod_name}" authors="baka4n,viola-Siemens,ENC-Euphony,wdog5734" +description='''${mod_name} for Minecraft 26.2.''' -# The description text for the mod (multi line!) (#mandatory) -description=''' -Example mod description. -''' - -# The [[mixins]] block allows you to declare your mixin config to FML so that it gets loaded. -[[mixins]] -config="${mod_id}.mixins.json" - -# The [[accessTransformers]] block allows you to declare where your AT file is. -# If this block is omitted, a fallback attempt will be made to load an AT from META-INF/accesstransformer.cfg -#[[accessTransformers]] -#file="META-INF/accesstransformer.cfg" +${module_mixins} -# The coremods config file path is not configurable and is always loaded from META-INF/coremods.json +[[dependencies.${mod_id}]] +modId="neoforge" +type="required" +versionRange="[${neo_version},)" +ordering="NONE" +side="BOTH" +[[dependencies.${mod_id}]] +modId="minecraft" +type="required" +versionRange="${minecraft_version_range}" +ordering="NONE" +side="BOTH" -# A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional. -[[dependencies.${mod_id}]] #optional - # the modid of the dependency - modId="neoforge" #mandatory - # The type of the dependency. Can be one of "required", "optional", "incompatible" or "discouraged" (case insensitive). - # 'required' requires the mod to exist, 'optional' does not - # 'incompatible' will prevent the game from loading when the mod exists, and 'discouraged' will show a warning - type="required" #mandatory - # Optional field describing why the dependency is required or why it is incompatible - # reason="..." - # The version range of the dependency - versionRange="[${neo_version},)" #mandatory - # An ordering relationship for the dependency. - # BEFORE - This mod is loaded BEFORE the dependency - # AFTER - This mod is loaded AFTER the dependency - ordering="NONE" - # Side this dependency is applied on - BOTH, CLIENT, or SERVER - side="BOTH" +${module_dependencies} -# Here's another dependency [[dependencies.${mod_id}]] - modId="minecraft" - type="required" - # This version range declares a minimum of the current minecraft version up to but not including the next major version - versionRange="${minecraft_version_range}" - ordering="NONE" - side="BOTH" - +modId="ww_hfas" +type="incompatible" +reason="Replace the old unified Wild Wind mod with the modular JARs." +ordering="NONE" +side="BOTH" [[dependencies.${mod_id}]] - modId="geckolib" - type="required" - versionRange="[${geocklib_version},)" - ordering="NONE" - side="BOTH" - -# Features are specific properties of the game environment, that you may want to declare you require. This example declares -# that your mod requires GL version 3.2 or higher. Other features will be added. They are side aware so declaring this won't -# stop your mod loading on the server for example. -#[features.${mod_id}] -#openGLVersion="[3.2,)" +modId="ww_structures" +type="incompatible" +reason="Structure generation is included in Wild Wind:Core." +ordering="NONE" +side="BOTH" diff --git a/src/verification/config/ww_structures/definitions/blocked.json b/src/verification/config/ww_structures/definitions/blocked.json new file mode 100644 index 0000000..4c0bbc2 --- /dev/null +++ b/src/verification/config/ww_structures/definitions/blocked.json @@ -0,0 +1,7 @@ +{ + "name": "blocked", + "template": "example_ruins.nbt", + "biomes": ["minecraft:plains"], + "placement": {"spacing": 2, "separation": 1, "salt": 123456}, + "conditions": {"min_y": 1000, "max_y": 1001} +} diff --git a/src/verification/config/ww_structures/definitions/disabled.json b/src/verification/config/ww_structures/definitions/disabled.json new file mode 100644 index 0000000..6997a49 --- /dev/null +++ b/src/verification/config/ww_structures/definitions/disabled.json @@ -0,0 +1,6 @@ +{ + "name": "disabled", + "enabled": false, + "template": "example_ruins.nbt", + "biomes": ["minecraft:plains"] +} diff --git a/src/verification/config/ww_structures/definitions/smoke.json b/src/verification/config/ww_structures/definitions/smoke.json new file mode 100644 index 0000000..b66cc37 --- /dev/null +++ b/src/verification/config/ww_structures/definitions/smoke.json @@ -0,0 +1,9 @@ +{ + "name": "smoke", + "template": "wide_ruins.nbt", + "biomes": ["minecraft:plains"], + "placement": {"spacing": 2, "separation": 1, "salt": 142857, "frequency": 1.0}, + "y_offset": -1, + "rotation": "clockwise_90", + "conditions": {"min_y": -2032, "max_y": 2031, "max_terrain_difference": 0, "avoid_fluids": true, "ground_blocks": ["#minecraft:dirt", "minecraft:grass_block"]} +} diff --git a/src/verification/config/ww_structures/templates/wide_ruins.nbt b/src/verification/config/ww_structures/templates/wide_ruins.nbt new file mode 100644 index 0000000..66d00f6 Binary files /dev/null and b/src/verification/config/ww_structures/templates/wide_ruins.nbt differ diff --git a/src/verification/java/org/polaris2023/wildwind/hfas/test/AzaleaAndArrowGameTests.java b/src/verification/java/org/polaris2023/wildwind/hfas/test/AzaleaAndArrowGameTests.java new file mode 100644 index 0000000..827e697 --- /dev/null +++ b/src/verification/java/org/polaris2023/wildwind/hfas/test/AzaleaAndArrowGameTests.java @@ -0,0 +1,241 @@ +package org.polaris2023.wildwind.hfas.test; + +import java.util.ArrayList; +import java.util.List; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.component.DataComponents; +import net.minecraft.core.registries.Registries; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.Identifier; +import net.minecraft.resources.ResourceKey; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.tags.ItemTags; +import net.minecraft.tags.TagKey; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.EntitySpawnReason; +import net.minecraft.world.entity.EntityTypes; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.projectile.arrow.AbstractArrow; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.DyeColor; +import net.minecraft.world.item.alchemy.PotionContents; +import net.minecraft.world.item.alchemy.Potions; +import net.minecraft.world.item.crafting.CraftingInput; +import net.minecraft.world.item.crafting.RecipeType; +import net.minecraft.world.level.GameType; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.ShelfBlock; +import net.minecraft.world.level.block.DispenserBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.ShelfBlockEntity; +import net.minecraft.world.level.block.entity.SignBlockEntity; +import net.minecraft.world.level.block.entity.SignText; +import net.minecraft.world.level.block.entity.HopperBlockEntity; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.storage.loot.LootParams; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; +import net.minecraft.world.level.storage.loot.parameters.LootContextParams; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.Vec3; +import org.polaris2023.wildwind.core.CoreMod; +import org.polaris2023.wildwind.wilderness.entity.ReachArrow; +import org.polaris2023.wildwind.wilderness.registry.ModEntities; +import org.polaris2023.wildwind.wilderness.registry.ModMobEffects; +import org.polaris2023.wildwind.wilderness.registry.ModPotions; + +final class AzaleaAndArrowGameTests { + private static void check(GameTestHelper h, boolean value, String message) { + h.assertTrue(value, Component.literal(message)); + } + + static void signs(GameTestHelper h) { + var level = h.getLevel(); + var blocks = List.of(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_SIGN.get(), org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_WALL_SIGN.get(), + org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_HANGING_SIGN.get(), org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_WALL_HANGING_SIGN.get()); + int x = 1; + for (var block : blocks) { + var rel = new BlockPos(x++, 2, 2); + var pos = h.absolutePos(rel); + var state = block.defaultBlockState(); + level.setBlock(pos, state, 2); + check(h, level.getBlockEntity(pos) instanceof SignBlockEntity, "All sign variants must create native sign entities"); + var sign = (SignBlockEntity) level.getBlockEntity(pos); + check(h, sign.getType().onlyOpCanSetNbt(), "Sign custom data must retain native administrator-only protection"); + check(h, sign.getType().isValid(state), "Native sign type must accept azalea blocks"); + sign.setText(new SignText().setMessage(0, Component.literal("Front")).setColor(DyeColor.RED).setHasGlowingText(true), true); + sign.setText(new SignText().setMessage(3, Component.literal("Back")), false); + sign.setWaxed(true); + var saved = sign.saveWithFullMetadata(level.registryAccess()); + var loaded = (SignBlockEntity) BlockEntity.loadStatic(pos, state, saved, level.registryAccess()); + check(h, loaded != null && loaded.isWaxed() && loaded.getFrontText().hasGlowingText() + && loaded.getFrontText().getColor() == DyeColor.RED + && loaded.getBackText().getMessage(3, false).getString().equals("Back"), "Both faces, dye, glow and wax must survive saving"); + check(h, state.getPistonPushReaction() == net.minecraft.world.level.material.PushReaction.BLOCK, "Signs must block pistons"); + check(h, state.getDestroySpeed(level, pos) == 1 && block.getExplosionResistance() == 1, "Sign hardness/resistance must be one"); + check(h, state.getFlammability(level, pos, Direction.UP) == 0, "Signs must not burn in fire"); + check(h, !Block.getDrops(state, level, pos, sign).isEmpty(), "Every sign variant must drop its item"); + check(h, state.hasProperty(BlockStateProperties.WATERLOGGED), "Signs must support waterlogging"); + } + check(h, org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_SIGN.get().asItem().getDefaultInstance().getMaxStackSize() == 16 + && org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_HANGING_SIGN.get().asItem().getDefaultInstance().getMaxStackSize() == 16, "Signs stack to 16"); + check(h, new ItemStack(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_SIGN.get()).getBurnTime(null, level.fuelValues()) == 200 + && new ItemStack(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_HANGING_SIGN.get()).getBurnTime(null, level.fuelValues()) == 800, "Sign fuel values must match specification"); + h.succeed(); + } + + static void shelf(GameTestHelper h) { + var level = h.getLevel(); + var rel = new BlockPos(3, 2, 3); + var pos = h.absolutePos(rel); + var state = org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_SHELF.get().defaultBlockState().setValue(ShelfBlock.FACING, Direction.NORTH); + level.setBlock(pos, state, 3); + var shelf = (ShelfBlockEntity) level.getBlockEntity(pos); + check(h, shelf != null && shelf.getType().isValid(state), "Shelf must use a valid native container"); + check(h, !shelf.getAlignItemsToBottom(), "Shelf display alignment must default to centered"); + for (int mask = 0; mask < 8; mask++) { + for (int slot = 0; slot < 3; slot++) shelf.setItem(slot, (mask & 1 << slot) == 0 ? ItemStack.EMPTY : new ItemStack(Items.DIAMOND, 64)); + check(h, state.getAnalogOutputSignal(level, pos, Direction.SOUTH) == mask, "Shelf comparator must encode all eight occupancy patterns"); + check(h, state.getAnalogOutputSignal(level, pos, Direction.NORTH) == 0, "Comparator only reads from the rear"); + } + shelf.clearContent(); + var player = h.makeMockPlayer(GameType.SURVIVAL); + player.setItemInHand(InteractionHand.MAIN_HAND, new ItemStack(Items.EMERALD, 32)); + h.useBlock(rel, player, new BlockHitResult(new Vec3(pos.getX() + 0.8, pos.getY() + 0.5, pos.getZ()), Direction.NORTH, pos, false)); + check(h, shelf.getItem(0).is(Items.EMERALD) && shelf.getItem(0).getCount() == 32 && player.getMainHandItem().isEmpty(), "Clicking left slot must swap the entire main-hand stack"); + player.setItemInHand(InteractionHand.MAIN_HAND, new ItemStack(Items.DIAMOND, 7)); + h.useBlock(rel, player, new BlockHitResult(new Vec3(pos.getX() + 0.8, pos.getY() + 0.5, pos.getZ()), Direction.NORTH, pos, false)); + check(h, shelf.getItem(0).is(Items.DIAMOND) && player.getMainHandItem().is(Items.EMERALD), "Occupied slot must return its previous stack"); + var saved = shelf.saveWithFullMetadata(level.registryAccess()); + saved.putBoolean("align_items_to_bottom", true); + var loaded = (ShelfBlockEntity) BlockEntity.loadStatic(pos, state, saved, level.registryAccess()); + check(h, loaded != null && loaded.getAlignItemsToBottom() && loaded.getItem(0).getCount() == 7, "Alignment and contents must persist"); + h.setBlock(3, 1, 3, Blocks.HOPPER); + var hopper = (HopperBlockEntity) level.getBlockEntity(pos.below()); + check(h, HopperBlockEntity.suckInItems(level, hopper) && hopper.getItem(0).is(Items.DIAMOND), "Hopper must extract leftmost occupied slot"); + check(h, level.getCapability(net.neoforged.neoforge.capabilities.Capabilities.Item.BLOCK, pos, Direction.UP) != null, "Shelf must expose native item capability"); + check(h, state.getFlammability(level, pos, Direction.UP) == 20 && state.getFireSpreadSpeed(level, pos, Direction.UP) == 30, "Shelf fire values must be 30/20"); + check(h, new ItemStack(org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_SHELF.get()).getBurnTime(null, level.fuelValues()) == 300, "Shelf fuel value must be 300"); + h.succeed(); + } + + static void shelfChain(GameTestHelper h) { + var level = h.getLevel(); + for (int count = 1; count <= 3; count++) { + for (int x = 1; x <= 4; x++) { + h.setBlock(x, 2, 3, Blocks.AIR); + h.setBlock(x, 1, 3, Blocks.AIR); + } + for (int x = 1; x <= count; x++) { + h.setBlock(x, 1, 3, Blocks.REDSTONE_BLOCK); + h.setBlock(x, 2, 3, org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_SHELF.get().defaultBlockState() + .setValue(ShelfBlock.FACING, Direction.NORTH).setValue(ShelfBlock.POWERED, true)); + } + var rel = new BlockPos(1, 2, 3); + var pos = h.absolutePos(rel); + check(h, org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_SHELF.get().getAllBlocksConnectedTo(level, pos).size() == count, "Powered shelf chain must connect up to three shelves"); + var player = h.makeMockPlayer(GameType.SURVIVAL); + for (int slot = 0; slot < 9; slot++) player.getInventory().setItem(slot, new ItemStack(Items.DIAMOND, slot + 1)); + h.useBlock(rel, player, new BlockHitResult(new Vec3(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ()), Direction.NORTH, pos, false)); + for (int slot = 0; slot < 9; slot++) check(h, player.getInventory().getItem(slot).isEmpty() == (slot >= 9 - 3 * count), "Powered shelves must swap rightmost 3/6/9 hotbar slots"); + h.useBlock(rel, player, new BlockHitResult(new Vec3(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ()), Direction.NORTH, pos, false)); + for (int slot = 0; slot < 9; slot++) check(h, player.getInventory().getItem(slot).getCount() == slot + 1, "Second swap must restore exact hotbar stacks"); + } + h.succeed(); + } + + static void arrows(GameTestHelper h) { + var level = h.getLevel(); + var owner = h.makeMockPlayer(GameType.SURVIVAL); + var target = EntityTypes.COW.create(level, EntitySpawnReason.COMMAND); + for (var potion : List.of(ModPotions.REACH, ModPotions.LONG_REACH)) { + var slots = new ArrayList(); + for (int i = 0; i < 9; i++) slots.add(new ItemStack(Items.ARROW)); + slots.set(4, PotionContents.createItemStack(Items.LINGERING_POTION, potion)); + var input = CraftingInput.of(3, 3, slots); + var recipe = level.recipeAccess().getRecipeFor(RecipeType.CRAFTING, input, level).orElseThrow(); + var result = recipe.value().assemble(input); + check(h, result.is(org.polaris2023.wildwind.wilderness.registry.ModItems.TIPPED_ARROW.get()) && result.getCount() == 8, "Vanilla surround recipe must produce eight mod Reach arrows"); + check(h, result.is(ItemTags.ARROWS), "Reach arrows must be valid bow and crossbow ammunition"); + var arrow = org.polaris2023.wildwind.wilderness.registry.ModItems.TIPPED_ARROW.get().createArrow(level, result, owner, new ItemStack(Items.BOW)); + check(h, arrow.getType() == ModEntities.REACH_ARROW.get() && arrow.getOwner() == owner, "Bow must spawn the custom arrow type with owner"); + check(h, !org.polaris2023.wildwind.wilderness.registry.ModItems.TIPPED_ARROW.get().isInfinite(result, new ItemStack(Items.BOW), owner), "Infinity must not save potion arrows"); + var hitArrow = new TestArrow(level, h.absoluteVec(new Vec3(2.5, 2.5, 2.5)), result); + target.removeAllEffects(); + hitArrow.hit(target); + int expected = potion == ModPotions.REACH ? 450 : 1200; + check(h, target.getEffect(ModMobEffects.REACH).getDuration() == expected, "Arrow must apply exactly 450/1200 ticks of Reach"); + h.setBlock(2, 2, 2, Blocks.STONE); + for (int tick = 0; tick < 599; tick++) hitArrow.tick(); + check(h, hitArrow.getPickupItemStackOrigin().is(org.polaris2023.wildwind.wilderness.registry.ModItems.TIPPED_ARROW.get()), "Potion must remain before 600 ground ticks"); + hitArrow.tick(); + check(h, hitArrow.getPickupItemStackOrigin().is(Items.ARROW) && hitArrow.getColor() == -1, "At 600 ground ticks pickup must become an ordinary arrow"); + } + check(h, DispenserBlock.DISPENSER_REGISTRY.containsKey(org.polaris2023.wildwind.wilderness.registry.ModItems.TIPPED_ARROW.get()), "Dispenser projectile behavior must be registered"); + var dispensed = org.polaris2023.wildwind.wilderness.registry.ModItems.TIPPED_ARROW.get().asProjectile(level, Vec3.ZERO, new ItemStack(org.polaris2023.wildwind.wilderness.registry.ModItems.TIPPED_ARROW.get()), Direction.NORTH); + check(h, dispensed.getType() == ModEntities.REACH_ARROW.get() && ((AbstractArrow) dispensed).pickup == AbstractArrow.Pickup.ALLOWED, "Dispensed arrows must be recoverable custom arrows"); + var poison = PotionContents.createItemStack(Items.TIPPED_ARROW, Potions.POISON); + check(h, org.polaris2023.wildwind.wilderness.arrow.ReachArrows.convert(poison) == poison, "Other potion arrows must remain vanilla"); + h.succeed(); + } + + static void acquisition(GameTestHelper h) { + var level = h.getLevel(); + var villager = EntityTypes.VILLAGER.create(level, EntitySpawnReason.COMMAND); + var tag = TagKey.create(Registries.POTION, Identifier.withDefaultNamespace("tradeable")); + var potions = level.registryAccess().lookupOrThrow(Registries.POTION).getOrThrow(tag); + check(h, potions.contains(ModPotions.REACH) && potions.contains(ModPotions.LONG_REACH), "Both Reach variants must join the survival potion trade pool"); + var params = new LootParams.Builder(level).withParameter(LootContextParams.ORIGIN, Vec3.ZERO) + .withParameter(LootContextParams.THIS_ENTITY, villager) + .withParameter(LootContextParams.ADDITIONAL_COST_COMPONENT_ALLOWED, net.minecraft.util.Unit.INSTANCE) + .create(LootContextParamSets.VILLAGER_TRADE); + var context = new LootContext.Builder(params).withOptionalRandomSeed(271828L).create(java.util.Optional.empty()); + var trades = level.registryAccess().lookupOrThrow(Registries.VILLAGER_TRADE); + var trade = trades.getOrThrow(ResourceKey.create(Registries.VILLAGER_TRADE, + Identifier.withDefaultNamespace("fletcher/5/arrow_and_emerald_tipped_arrow"))).value(); + var set = level.registryAccess().lookupOrThrow(Registries.TRADE_SET).getOrThrow(ResourceKey.create(Registries.TRADE_SET, + Identifier.withDefaultNamespace("fletcher/level_5"))).value(); + check(h, set.calculateNumberOfTrades(context) == 2 && set.getTrades().size() == 3 && !set.allowDuplicates(), + "Master fletcher must keep vanilla two-of-three trade selection"); + boolean normal = false, longReach = false, other = false; + for (int i = 0; i < 2048; i++) { + var offer = trade.getOffer(context); + check(h, offer != null && offer.getBaseCostA().is(Items.EMERALD) && offer.getBaseCostA().getCount() == 2 + && offer.getCostB().is(Items.ARROW) && offer.getCostB().getCount() == 5 && offer.getResult().getCount() == 5, + "Fletcher potion-arrow cost must remain two emeralds plus five arrows for five arrows"); + var result = offer.getResult(); + if (result.is(org.polaris2023.wildwind.wilderness.registry.ModItems.TIPPED_ARROW.get())) { + var potion = result.get(DataComponents.POTION_CONTENTS).potion().orElseThrow(); + normal |= potion.is(ModPotions.REACH.getKey()); + longReach |= potion.is(ModPotions.LONG_REACH.getKey()); + } else other |= result.is(Items.TIPPED_ARROW); + } + check(h, normal && longReach && other, "Random trade must offer both custom Reach arrows and vanilla alternatives"); + var gift = level.getServer().reloadableRegistries().getLootTable(ResourceKey.create(Registries.LOOT_TABLE, + Identifier.withDefaultNamespace("gameplay/hero_of_the_village/fletcher_gift"))); + var giftParams = new LootParams.Builder(level).withParameter(LootContextParams.ORIGIN, Vec3.ZERO) + .withParameter(LootContextParams.THIS_ENTITY, villager).create(LootContextParamSets.GIFT); + var random = net.minecraft.util.RandomSource.create(314159L); + boolean reachGift = false, vanillaGift = false; + for (int i = 0; i < 1024; i++) { + var results = gift.getRandomItems(giftParams, random); + check(h, results.size() <= 1, "Reach gift must join the existing random choice, not add an extra gift"); + for (var result : results) { + reachGift |= result.is(org.polaris2023.wildwind.wilderness.registry.ModItems.TIPPED_ARROW.get()); + vanillaGift |= result.is(Items.ARROW) || result.is(Items.TIPPED_ARROW); + } + } + check(h, reachGift && vanillaGift, "Hero gifts must include Reach and preserve vanilla choices"); + h.succeed(); + } + + private static class TestArrow extends ReachArrow { + TestArrow(Level level, Vec3 pos, ItemStack stack) { super(level, pos.x, pos.y, pos.z, stack, null); } + void hit(LivingEntity target) { doPostHurtEffects(target); } + } +} diff --git a/src/verification/java/org/polaris2023/wildwind/hfas/test/BookInspectionGameTests.java b/src/verification/java/org/polaris2023/wildwind/hfas/test/BookInspectionGameTests.java new file mode 100644 index 0000000..43b1642 --- /dev/null +++ b/src/verification/java/org/polaris2023/wildwind/hfas/test/BookInspectionGameTests.java @@ -0,0 +1,169 @@ +package org.polaris2023.wildwind.hfas.test; + +import java.util.List; +import java.util.stream.IntStream; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.component.DataComponents; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.network.chat.Component; +import net.minecraft.server.network.Filterable; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.EntityTypes; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.component.WritableBookContent; +import net.minecraft.world.level.GameType; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.piston.PistonBaseBlock; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.Vec3; +import net.neoforged.neoforge.common.NeoForge; +import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent; +import org.polaris2023.wildwind.core.inspection.BookInspectionHandler; +import org.polaris2023.wildwind.core.inspection.InspectionReport; +import org.polaris2023.wildwind.core.inspection.SulfurProfile; + +public final class BookInspectionGameTests { + private static void check(GameTestHelper h, boolean ok, String message) { h.assertTrue(ok, Component.literal(message)); } + private static void field(GameTestHelper h, List report, String row) { check(h, report.contains(row), "Missing report row: " + row + " in " + report); } + + static void blocks(GameTestHelper h) { + var level = h.getLevel(); + var pos = h.absolutePos(new BlockPos(2, 2, 2)); + level.setBlockAndUpdate(pos, Blocks.OAK_PLANKS.defaultBlockState()); + var report = InspectionReport.block(level, pos); + for (String row : List.of("方块ID:minecraft:oak_planks", "硬度:2", "爆炸抗性:3", "引燃几率:5", "烧毁几率:20", + "熔岩可燃性:是", "乐器:贝斯", "烧炼时间:15秒(300刻)", "最大堆叠:64", "可再生:是", "物品ID:minecraft:oak_planks")) field(h, report, row); + check(h, report.stream().anyMatch(row -> row.startsWith("合适挖掘工具:") && row.contains("斧")), "Planks use axes"); + level.setBlockAndUpdate(pos, Blocks.COBBLESTONE.defaultBlockState()); + report = InspectionReport.block(level, pos); + field(h, report, "引燃几率:×"); + field(h, report, "烧炼时间:×"); + field(h, report, "烧炼加工时间:10秒(200刻)"); + level.setBlockAndUpdate(pos, Blocks.WATER.defaultBlockState()); + field(h, InspectionReport.block(level, pos), "物品ID:×"); + field(h, InspectionReport.block(level, pos), "最大堆叠:×"); + level.setBlockAndUpdate(pos, Blocks.DIAMOND_BLOCK.defaultBlockState()); + field(h, InspectionReport.block(level, pos), "可再生:否"); + level.setBlockAndUpdate(pos, Blocks.BARRIER.defaultBlockState()); + field(h, InspectionReport.block(level, pos), "可再生:×"); + level.setBlockAndUpdate(pos, org.polaris2023.wildwind.core.block.ModBlocks.AZALEA_PLANKS.get().defaultBlockState()); + report = InspectionReport.block(level, pos); + field(h, report, "方块ID:wild_wind_core:azalea_planks"); + field(h, report, "可再生:是"); + field(h, report, "烧炼时间:15秒(300刻)"); + for (var block : List.of(Blocks.OBSIDIAN, Blocks.CHEST, Blocks.BEDROCK)) { + check(h, InspectionReport.piston(block.defaultBlockState(), level, pos).equals("不可推动,不可拉动"), "Special immovable block: " + block); + } + check(h, InspectionReport.piston(Blocks.STONE.defaultBlockState(), level, pos).equals("可推动,可拉动"), "Stone is movable"); + check(h, InspectionReport.piston(Blocks.TORCH.defaultBlockState(), level, pos).equals("被推动破坏,不可拉动"), "Torch breaks when pushed"); + check(h, InspectionReport.piston(Blocks.GLAZED_TERRACOTTA.white().defaultBlockState(), level, pos).equals("可推动,不可拉动"), "Glazed terracotta push-only"); + check(h, InspectionReport.piston(Blocks.PISTON.defaultBlockState().setValue(PistonBaseBlock.EXTENDED, true), level, pos).equals("不可推动,不可拉动"), "Extended piston immovable"); + h.succeed(); + } + + static void interactions(GameTestHelper h) { + var player = h.makeMockServerPlayerInLevel(); + var pos = h.absolutePos(new BlockPos(2, 2, 2)); + h.getLevel().setBlockAndUpdate(pos, Blocks.CHEST.defaultBlockState()); + var book = new ItemStack(Items.WRITABLE_BOOK); + var note = new Filterable<>("已有笔记,请保留", java.util.Optional.of("过滤后的笔记")); + book.set(DataComponents.WRITABLE_BOOK_CONTENT, new WritableBookContent(List.of(note))); + player.setItemInHand(InteractionHand.MAIN_HAND, book); + var hit = new BlockHitResult(Vec3.atCenterOf(pos), Direction.UP, pos, false); + var normal = NeoForge.EVENT_BUS.post(new PlayerInteractEvent.RightClickBlock(player, InteractionHand.MAIN_HAND, pos, hit)); + check(h, !normal.isCanceled() && book.get(DataComponents.WRITABLE_BOOK_CONTENT).pages().size() == 1, "Normal use must remain unchanged"); + player.setShiftKeyDown(true); + var event = NeoForge.EVENT_BUS.post(new PlayerInteractEvent.RightClickBlock(player, InteractionHand.MAIN_HAND, pos, hit)); + check(h, event.isCanceled() && event.getCancellationResult() == InteractionResult.SUCCESS, "Inspector consumes interaction before opening chest/book"); + var signed = player.getItemInHand(InteractionHand.MAIN_HAND); + check(h, signed.is(Items.WRITTEN_BOOK) && !signed.has(DataComponents.WRITABLE_BOOK_CONTENT), "Held book becomes signed book without editable pages"); + var content = signed.get(DataComponents.WRITTEN_BOOK_CONTENT); + var pages = content.pages(); + check(h, pages.size() > 1 && pages.getFirst().equals(note.map(Component::literal)), "Signing preserves raw and filtered notes"); + check(h, content.author().equals(player.getGameProfile().name()) && content.generation() == 0 && content.resolved(), "Player is author of original literal snapshot"); + String chestName = Blocks.CHEST.getName().getString() + "(minecraft:chest)"; + check(h, content.title().raw().equals(chestName) && signed.getHoverName().getString().equals(chestName), "Signed title includes block name and ID"); + check(h, pages.stream().allMatch(p -> p.raw().getString().length() <= 1024 && p.raw().getString().split("\n", -1).length <= 12), "Pages fit book layout limits"); + var repeated = NeoForge.EVENT_BUS.post(new PlayerInteractEvent.RightClickBlock(player, InteractionHand.MAIN_HAND, pos, hit)); + check(h, !repeated.isCanceled() && player.getItemInHand(InteractionHand.MAIN_HAND) == signed, "Signed book is never inspected again"); + var full = new WritableBookContent(IntStream.range(0, 100).mapToObj(i -> Filterable.passThrough("note " + i)).toList()); + book.set(DataComponents.WRITABLE_BOOK_CONTENT, full); + player.setItemInHand(InteractionHand.MAIN_HAND, book); + NeoForge.EVENT_BUS.post(new PlayerInteractEvent.RightClickBlock(player, InteractionHand.MAIN_HAND, pos, hit)); + check(h, player.getItemInHand(InteractionHand.MAIN_HAND) == book && book.get(DataComponents.WRITABLE_BOOK_CONTENT).equals(full), "Full held book is unchanged"); + var almostFull = new WritableBookContent(full.pages().subList(0, 99)); + book.set(DataComponents.WRITABLE_BOOK_CONTENT, almostFull); + check(h, BookInspectionHandler.sign(book, List.of("one", "two"), Component.literal("test"), "author").isEmpty() + && book.get(DataComponents.WRITABLE_BOOK_CONTENT).equals(almostFull), "Insufficient space never partially appends a report"); + player.setItemInHand(InteractionHand.MAIN_HAND, ItemStack.EMPTY); + var offhand = new ItemStack(Items.WRITABLE_BOOK); + player.setItemInHand(InteractionHand.OFF_HAND, offhand); + var cow = h.spawn(EntityTypes.COW, 3, 2, 3); + var entityEvent = NeoForge.EVENT_BUS.post(new PlayerInteractEvent.EntityInteract(player, InteractionHand.OFF_HAND, cow, Vec3.ZERO)); + var signedEntity = player.getItemInHand(InteractionHand.OFF_HAND); + check(h, entityEvent.isCanceled() && signedEntity.is(Items.WRITTEN_BOOK) + && !signedEntity.get(DataComponents.WRITTEN_BOOK_CONTENT).pages().isEmpty() + && signedEntity.getHoverName().getString().equals(cow.getType().getDescription().getString() + "(minecraft:cow)") + && player.getItemInHand(InteractionHand.MAIN_HAND).isEmpty(), "Offhand entity interaction replaces only the offhand book"); + var report = InspectionReport.entity(h.getLevel(), cow); + field(h, report, "实体ID:minecraft:cow"); field(h, report, "方块ID:×"); field(h, report, "硬度:×"); field(h, report, "最大生命值:10"); + field(h, report, "物品ID:×"); field(h, report, "可再生:是"); + var observer = h.makeMockServerPlayer(GameType.SPECTATOR); + observer.setShiftKeyDown(true); + observer.setItemInHand(InteractionHand.OFF_HAND, offhand); + var spectator = NeoForge.EVENT_BUS.post(new PlayerInteractEvent.EntityInteract(observer, InteractionHand.OFF_HAND, cow, Vec3.ZERO)); + check(h, !spectator.isCanceled(), "Spectators never write"); + var dropped = new net.minecraft.world.entity.item.ItemEntity(h.getLevel(), 0, 0, 0, new ItemStack(Items.COBBLESTONE, 12)); + var itemReport = InspectionReport.entity(h.getLevel(), dropped); + field(h, itemReport, "实体ID:minecraft:item"); + field(h, itemReport, "物品ID:minecraft:cobblestone"); + field(h, itemReport, "最大堆叠:64"); + field(h, itemReport, "生命值:×"); + check(h, BookInspectionHandler.sign(signedEntity, List.of("overwrite"), Component.literal("test"), "author").isEmpty(), "Signed books cannot be changed"); + var longName = Component.literal("杜鹃木悬挂式告示牌(wild_wind_core:azalea_hanging_sign)"); + var longBook = BookInspectionHandler.sign(offhand, List.of("report"), longName, "author"); + check(h, longBook.getHoverName().equals(longName), "Full name and long ID are preserved for display"); + var longContent = longBook.get(DataComponents.WRITTEN_BOOK_CONTENT); + check(h, longContent.title().raw().length() <= 32 + && net.minecraft.world.item.component.WrittenBookContent.CODEC.encodeStart( + h.getLevel().registryAccess().createSerializationContext(com.mojang.serialization.JsonOps.INSTANCE), longContent).isSuccess(), + "Long titles serialize within vanilla limits"); + var unicodeBook = BookInspectionHandler.sign(offhand, List.of("report"), Component.literal("x".repeat(31) + "😀(minecraft:stone)"), "author"); + check(h, unicodeBook.get(DataComponents.WRITTEN_BOOK_CONTENT).title().raw().equals("x".repeat(31)), "Title truncation preserves surrogate pairs"); + h.succeed(); + } + + static void sulfur(GameTestHelper h) { + var level = h.getLevel(); + var examples = List.of(Items.OAK_PLANKS, Items.MUD, Items.IRON_BLOCK, Items.MOSS_BLOCK, Items.WOOL.white(), + Items.PACKED_ICE, Items.RED_MUSHROOM_BLOCK, Items.STONE, Items.HONEYCOMB_BLOCK, Items.SOUL_SAND, Items.TNT, Items.MAGMA_BLOCK); + var names = List.of("弹性(橡胶球)", "普通(足球)", "缓慢平移(药球)", "快速平移(高尔夫球)", "轻盈(沙滩球)", + "快速滑行(冰球)", "缓慢滑行(冰壶)", "缓慢弹性", "黏性", "高阻力", "爆炸", "高温"); + var cubes = new java.util.ArrayList(); + for (int i = 0; i < examples.size(); i++) { + var stack = examples.get(i).getDefaultInstance(); + var profile = SulfurProfile.of(level, stack); + check(h, profile.name().equals(names.get(i)), "Vanilla archetype membership for " + stack + ": " + profile.name()); + var cube = h.spawn(EntityTypes.SULFUR_CUBE, 2, 2, 2); + cube.setNoAi(true); + cube.setItemSlot(EquipmentSlot.BODY, stack); + cubes.add(cube); + } + check(h, SulfurProfile.of(level, Items.STICK.getDefaultInstance()).name().equals("默认"), "Unmatched items use default archetype"); + h.runAfterDelay(3, () -> { + for (var cube : cubes) { + var profile = SulfurProfile.of(level, cube.getItemBySlot(EquipmentSlot.BODY)); + field(h, InspectionReport.entity(level, cube), "硫方怪原型:" + profile.name()); + for (var attribute : List.of(Attributes.KNOCKBACK_RESISTANCE, Attributes.BOUNCINESS, Attributes.FRICTION_MODIFIER, Attributes.AIR_DRAG_MODIFIER)) { + check(h, Math.abs(profile.attribute(attribute) - cube.getAttributeValue(attribute)) < 0.0001, "Inspector physics agrees with actual equipped sulfur cube: " + profile.name()); + } + } + h.succeed(); + }); + } +} diff --git a/src/verification/java/org/polaris2023/wildwind/hfas/test/EnchantmentTableGameTests.java b/src/verification/java/org/polaris2023/wildwind/hfas/test/EnchantmentTableGameTests.java new file mode 100644 index 0000000..ad82e89 --- /dev/null +++ b/src/verification/java/org/polaris2023/wildwind/hfas/test/EnchantmentTableGameTests.java @@ -0,0 +1,66 @@ +package org.polaris2023.wildwind.hfas.test; + +import java.util.List; +import net.minecraft.core.BlockPos; +import net.minecraft.core.component.DataComponents; +import net.minecraft.core.registries.Registries; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.network.chat.Component; +import net.minecraft.tags.EnchantmentTags; +import net.minecraft.world.inventory.ContainerLevelAccess; +import net.minecraft.world.inventory.EnchantmentMenu; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.enchantment.EnchantmentHelper; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.EnchantingTableBlock; +import org.polaris2023.wildwind.core.enchantment.MeltingEnchantment; + +public final class EnchantmentTableGameTests { + private static void check(GameTestHelper h, boolean ok, String message) { + h.assertTrue(ok, Component.literal(message)); + } + + static void melting(GameTestHelper h) { + var level = h.getLevel(); + var registry = level.registryAccess().lookupOrThrow(Registries.ENCHANTMENT); + var melting = registry.getOrThrow(MeltingEnchantment.MELTING); + var tablePool = registry.getOrThrow(EnchantmentTags.IN_ENCHANTING_TABLE); + check(h, tablePool.contains(melting), "Melting belongs to the real enchanting-table pool"); + for (var item : List.of(Items.DIAMOND_CHESTPLATE, Items.DIAMOND_SWORD)) { + check(h, EnchantmentHelper.getAvailableEnchantmentResults(30, new ItemStack(item), tablePool.stream()) + .stream().noneMatch(e -> e.enchantment().equals(melting)), "Melting is not offered for " + item); + } + + var player = h.makeMockServerPlayerInLevel(); + var pos = h.absolutePos(new BlockPos(3, 2, 3)); + level.setBlockAndUpdate(pos, Blocks.ENCHANTING_TABLE.defaultBlockState()); + for (var offset : EnchantingTableBlock.BOOKSHELF_OFFSETS) { + level.setBlockAndUpdate(pos.offset(offset), Blocks.BOOKSHELF.defaultBlockState()); + } + int meltingId = registry.asHolderIdMap().getId(melting); + for (var item : List.of(Items.DIAMOND_PICKAXE, Items.DIAMOND_AXE, Items.DIAMOND_SHOVEL, Items.DIAMOND_HOE, Items.BOOK)) { + boolean obtained = false; + var menu = new EnchantmentMenu(1, player.getInventory(), ContainerLevelAccess.create(level, pos)); + menu.getSlot(1).set(new ItemStack(Items.LAPIS_LAZULI, 64)); + // Data slot 3 is vanilla's synchronized enchantment seed. Fixed seeds make the + // test reproducible while exercising real offers and the menu's apply path. + for (int seed = 0; seed < 2048 && !obtained; seed++) { + menu.setData(3, seed); + menu.getSlot(0).set(new ItemStack(item)); + for (int slot = 0; slot < 3; slot++) { + if (menu.enchantClue[slot] != meltingId) continue; + check(h, menu.clickMenuButton(player, slot), "Enchanting-table offer can be selected"); + var result = menu.getSlot(0).getItem(); + var enchantments = result.get(item == Items.BOOK ? DataComponents.STORED_ENCHANTMENTS : DataComponents.ENCHANTMENTS); + check(h, enchantments != null && enchantments.getLevel(melting) == 1, "Table actually applies Melting I"); + check(h, item != Items.BOOK || result.is(Items.ENCHANTED_BOOK), "Table transforms a normal book"); + obtained = true; + break; + } + } + check(h, obtained, "Melting can be randomly obtained from the table on " + item); + } + h.succeed(); + } +} diff --git a/src/verification/java/org/polaris2023/wildwind/hfas/test/FluidEntityRulesGameTests.java b/src/verification/java/org/polaris2023/wildwind/hfas/test/FluidEntityRulesGameTests.java new file mode 100644 index 0000000..fcc604e --- /dev/null +++ b/src/verification/java/org/polaris2023/wildwind/hfas/test/FluidEntityRulesGameTests.java @@ -0,0 +1,218 @@ +package org.polaris2023.wildwind.hfas.test; + +import java.util.List; +import java.util.Set; +import java.util.HashSet; +import net.minecraft.tags.TagKey; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.registries.Registries; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.network.chat.Component; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.tags.EntityTypeTags; +import net.minecraft.tags.FluidTags; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.effect.MobEffects; +import net.minecraft.world.entity.EntitySpawnReason; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.EntityTypes; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.MoverType; +import net.minecraft.world.level.GameType; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.phys.Vec3; +import net.neoforged.neoforge.common.CommonHooks; +import org.polaris2023.wildwind.wilderness.effect.FluidEffects; +import org.polaris2023.wildwind.wilderness.effect.ModEffects; +import org.polaris2023.wildwind.wilderness.entity.ModEntityTypeTags; + +final class FluidEntityRulesGameTests { + private FluidEntityRulesGameTests() {} + + private static void check(GameTestHelper h, boolean condition, String message) { + h.assertTrue(condition, Component.literal(message)); + } + + private static LivingEntity submerged(GameTestHelper h, EntityType type) { + var entity = type == EntityTypes.PLAYER ? h.makeMockServerPlayer(GameType.SURVIVAL) + : (LivingEntity) type.create(h.getLevel(), EntitySpawnReason.COMMAND); + check(h, entity != null, "Must create test entity " + type); + if (entity instanceof ServerPlayer player) { + var connection = new net.minecraft.network.Connection(net.minecraft.network.protocol.PacketFlow.SERVERBOUND); + new io.netty.channel.embedded.EmbeddedChannel(connection); + h.getLevel().getServer().getPlayerList().placeNewPlayer(connection, player, + net.minecraft.server.network.CommonListenerCookie.createInitial(player.getGameProfile(), false)); + } + if (entity instanceof Mob mob) mob.setNoAi(true); + entity.setNoGravity(true); + entity.setPos(h.absoluteVec(new Vec3(3.5, 1.5, 3.5))); + // Initialize actual fluid contact and eye immersion without adding mobs to the world. + entity.baseTick(); + check(h, entity.isEyeInFluid(FluidTags.WATER), "Test entity must be submerged: " + type); + return entity; + } + + static void run(GameTestHelper h) { + for (int x = 1; x <= 6; x++) for (int y = 1; y <= 4; y++) for (int z = 1; z <= 6; z++) { + h.setBlock(x, y, z, Blocks.WATER); + } + var registry = h.getLevel().registryAccess().lookupOrThrow(Registries.ENTITY_TYPE); + var protectedTypes = registry.getOrThrow(ModEntityTypeTags.WATER_BREATHING); + check(h, protectedTypes.size() >= 25, "All 25 distinct requested vanilla water-breathing types must load"); + for (var holder : protectedTypes) { + var entity = submerged(h, holder.value()); + check(h, entity.is(EntityTypeTags.CAN_BREATHE_UNDER_WATER), "Vanilla breathing tag must include " + holder); + entity.addEffect(new MobEffectInstance(ModEffects.CHOKE, 200, 3)); + entity.setAirSupply(-20); + float health = entity.getHealth(); + CommonHooks.onLivingBreathe(entity, h.getLevel(), 1, 4); + check(h, entity.getAirSupply() == entity.getMaxAirSupply() && entity.getHealth() == health, + "Protected type must recover empty air and resist Choke without drowning: " + holder); + entity.addEffect(new MobEffectInstance(ModEffects.SINK, 200)); + check(h, !FluidEffects.cannotRise(entity), "Unlisted water-breather must not be affected by Sink: " + holder); + } + + var affectedTypes = registry.getOrThrow(ModEntityTypeTags.SINK_AFFECTED); + assertWhitelist(h, ModEntityTypeTags.SINK_AFFECTED, """ + player fox camel camel_husk chicken mooshroom cow donkey horse mule parrot pig rabbit sheep + sniffer tadpole turtle wandering_trader goat villager axolotl cat frog ocelot snow_golem bee + panda iron_golem llama polar_bear trader_llama wolf evoker hoglin piglin_brute pillager + ravager vindicator warden witch piglin + """); + assertWhitelist(h, ModEntityTypeTags.CHOKE_AFFECTED, """ + player fox camel camel_husk chicken mooshroom cow donkey horse mule parrot pig rabbit sheep + sniffer turtle wandering_trader goat villager cat frog ocelot snow_golem bee panda iron_golem + llama polar_bear trader_llama wolf evoker hoglin piglin_brute pillager ravager vindicator + warden witch creeper cave_spider spider enderman piglin + """); + for (var holder : affectedTypes) { + var entity = submerged(h, holder.value()); + entity.addEffect(new MobEffectInstance(ModEffects.SINK, 200)); + double y = entity.getY(); + entity.move(MoverType.SELF, new Vec3(0, 0.1, 0)); + check(h, entity.getY() == y, "Sink must prevent actual upward motion for " + holder); + entity.removeEffect(ModEffects.SINK); + entity.move(MoverType.SELF, new Vec3(0, 0.1, 0)); + check(h, entity.getY() > y, "Removing Sink must restore upward motion for " + holder); + } + + for (var type : List.of(EntityTypes.BAT, EntityTypes.CREEPER, EntityTypes.SPIDER, + EntityTypes.PHANTOM, EntityTypes.COD)) { + var entity = submerged(h, type); + entity.addEffect(new MobEffectInstance(ModEffects.SINK, 200)); + double y = entity.getY(); + entity.move(MoverType.SELF, new Vec3(0, 0.1, 0)); + check(h, entity.getY() > y, "Unlisted type/subclass must retain upward movement: " + type); + } + + for (var holder : registry.getOrThrow(ModEntityTypeTags.CHOKE_AFFECTED)) { + var type = holder.value(); + var entity = submerged(h, type); + entity.addEffect(new MobEffectInstance(ModEffects.CHOKE, 200)); + entity.setAirSupply(200); + entity.baseTick(); + check(h, entity.getAirSupply() == 198, "Choke I must double actual underwater air loss: " + type); + entity.setAirSupply(200); + CommonHooks.onLivingBreathe(entity, h.getLevel(), 0, 4); + check(h, entity.getAirSupply() == 200, "Choke must preserve Respiration's skipped consumption: " + type); + entity.addEffect(new MobEffectInstance(ModEffects.CHOKE, 200, 1)); + entity.baseTick(); + check(h, entity.getAirSupply() == 197, "Choke II must triple underwater air loss: " + type); + entity.addEffect(new MobEffectInstance(MobEffects.WATER_BREATHING, 200)); + entity.setAirSupply(200); + entity.baseTick(); + check(h, entity.getAirSupply() >= 200, "Water Breathing must protect against Choke: " + type); + entity.removeEffect(MobEffects.WATER_BREATHING); + entity.setPos(h.absoluteVec(new Vec3(3.5, 6, 3.5))); + entity.baseTick(); + entity.setAirSupply(200); + entity.baseTick(); + check(h, entity.getAirSupply() == 204, "Ordinary Choke targets must recover air on land: " + type); + } + for (var type : List.of(EntityTypes.BAT, EntityTypes.ALLAY)) { + var entity = submerged(h, type); + entity.addEffect(new MobEffectInstance(ModEffects.CHOKE, 200, 2)); + entity.setAirSupply(200); + entity.baseTick(); + check(h, entity.getAirSupply() == 199, "Unlisted types must retain normal air consumption: " + type); + } + var phantom = submerged(h, EntityTypes.PHANTOM); + phantom.addEffect(new MobEffectInstance(ModEffects.SINK, 200)); + phantom.addEffect(new MobEffectInstance(ModEffects.CHOKE, 200)); + phantom.setAirSupply(0); + CommonHooks.onLivingBreathe(phantom, h.getLevel(), 1, 4); + check(h, !FluidEffects.cannotRise(phantom) && phantom.getAirSupply() > 0, + "Phantom must now resist both effects"); + var player = (ServerPlayer) submerged(h, EntityTypes.PLAYER); + // The mock fixes gameMode() to its constructor value; set the abilities used by the breathing hook. + GameType.CREATIVE.updatePlayerAbilities(player.getAbilities()); + player.addEffect(new MobEffectInstance(ModEffects.CHOKE, 200)); + player.setAirSupply(200); + player.baseTick(); + check(h, player.getAirSupply() >= 200, "Creative invulnerability must protect against Choke: air=" + + player.getAirSupply() + ", invulnerable=" + player.getAbilities().invulnerable); + h.succeed(); + } + + private static void assertWhitelist(GameTestHelper h, TagKey> tag, String vanillaNames) { + Set expected = new HashSet<>(); + for (String name : vanillaNames.strip().split("\\s+")) expected.add("minecraft:" + name); + expected.add("wild_wind_wilderness:muddy_pig"); + Set actual = new HashSet<>(); + for (var holder : h.getLevel().registryAccess().lookupOrThrow(Registries.ENTITY_TYPE).getOrThrow(tag)) { + actual.add(BuiltInRegistries.ENTITY_TYPE.getKey(holder.value()).toString()); + } + check(h, actual.equals(expected), "Exact whitelist must match " + tag + ": " + actual); + } + + static void landChoke(GameTestHelper h) { + for (int x = 1; x <= 6; x++) for (int y = 1; y <= 4; y++) for (int z = 1; z <= 6; z++) { + h.setBlock(x, y, z, Blocks.WATER); + } + // Keep the dry position sheltered so rain cannot rehydrate the axolotl. + h.setBlock(3, 8, 3, Blocks.STONE); + for (var type : List.of(EntityTypes.TADPOLE, EntityTypes.AXOLOTL)) { + var entity = submerged(h, type); + ((Mob) entity).setNoAi(false); + check(h, !entity.is(ModEntityTypeTags.CHOKE_AFFECTED), "Land-only types must not enter the water Choke tag"); + entity.addEffect(new MobEffectInstance(ModEffects.CHOKE, 200)); + entity.setAirSupply(200); + entity.baseTick(); + check(h, entity.getAirSupply() == entity.getMaxAirSupply(), "Choke must not affect submerged " + type); + entity.setPos(h.absoluteVec(new Vec3(3.5, 6, 3.5))); + entity.baseTick(); + check(h, !entity.isInWater(), "Special Choke test must be on dry land"); + entity.setAirSupply(200); + entity.baseTick(); + check(h, entity.getAirSupply() == 198, "Choke I must double real land drying: " + type); + entity.addEffect(new MobEffectInstance(ModEffects.CHOKE, 200, 1)); + entity.setAirSupply(200); + entity.baseTick(); + check(h, entity.getAirSupply() == 197, "Choke II must triple real land drying: " + type); + entity.removeEffect(ModEffects.CHOKE); + entity.setAirSupply(200); + entity.baseTick(); + check(h, entity.getAirSupply() == 199, "Removing Choke must restore vanilla drying: " + type); + entity.addEffect(new MobEffectInstance(ModEffects.CHOKE, 200)); + entity.setAirSupply(-18); + entity.invulnerableTime = 0; + float health = entity.getHealth(); + entity.baseTick(); + check(h, entity.getHealth() == health - 2 && entity.getAirSupply() == 0, + "Land Choke must use vanilla drying damage exactly once: " + type + + ", health " + health + " -> " + entity.getHealth() + ", air=" + entity.getAirSupply()); + entity.setPos(h.absoluteVec(new Vec3(3.5, 1.5, 3.5))); + entity.baseTick(); + check(h, entity.getAirSupply() == entity.getMaxAirSupply(), "Returning to water must stop Choke and refill air: " + type); + } + var cod = submerged(h, EntityTypes.COD); + cod.addEffect(new MobEffectInstance(ModEffects.CHOKE, 200, 2)); + cod.setPos(h.absoluteVec(new Vec3(3.5, 6, 3.5))); + cod.baseTick(); + cod.setAirSupply(200); + cod.baseTick(); + check(h, cod.getAirSupply() == 199, "Shared WaterAnimal mixin must not accelerate other fish drying"); + h.succeed(); + } +} diff --git a/src/verification/java/org/polaris2023/wildwind/hfas/test/GameplayGameTests.java b/src/verification/java/org/polaris2023/wildwind/hfas/test/GameplayGameTests.java new file mode 100644 index 0000000..ba2bc64 --- /dev/null +++ b/src/verification/java/org/polaris2023/wildwind/hfas/test/GameplayGameTests.java @@ -0,0 +1,274 @@ +package org.polaris2023.wildwind.hfas.test; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; +import net.minecraft.core.BlockPos; +import net.minecraft.core.component.DataComponents; +import net.minecraft.core.registries.Registries; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.network.chat.Component; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.tags.ItemTags; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.effect.MobEffects; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityTypes; +import net.minecraft.world.entity.MoverType; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.inventory.ContainerLevelAccess; +import net.minecraft.world.inventory.CraftingMenu; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.crafting.CraftingInput; +import net.minecraft.world.item.crafting.RecipeType; +import net.minecraft.world.item.enchantment.Enchantments; +import net.minecraft.world.level.GameType; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.entity.CrafterBlockEntity; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.Vec3; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.neoforge.common.CommonHooks; +import net.neoforged.neoforge.common.NeoForge; +import net.neoforged.neoforge.event.level.BlockDropsEvent; +import net.neoforged.neoforge.registries.DeferredRegister; +import org.polaris2023.wildwind.wilderness.effect.ModEffects; +import org.polaris2023.wildwind.core.enchantment.MeltingEnchantment; +import org.polaris2023.wildwind.core.event.CobwebBreaking; +import org.polaris2023.wildwind.core.recipe.WoolToStringRecipe; + +public final class GameplayGameTests { + private GameplayGameTests() {} + public static void register(IEventBus bus) { + DeferredRegister> tests = DeferredRegister.create(Registries.TEST_FUNCTION, "wild_wind_tests"); + tests.register("wool_recipe", () -> GameplayGameTests::woolRecipe); + tests.register("crafter_shears", () -> GameplayGameTests::crafterShears); + tests.register("fluid_effects", () -> GameplayGameTests::fluidEffects); + tests.register("fluid_entity_rules", () -> FluidEntityRulesGameTests::run); + tests.register("land_choke", () -> FluidEntityRulesGameTests::landChoke); + tests.register("azalea_signs", () -> AzaleaAndArrowGameTests::signs); + tests.register("azalea_shelf", () -> AzaleaAndArrowGameTests::shelf); + tests.register("azalea_shelf_chain", () -> AzaleaAndArrowGameTests::shelfChain); + tests.register("reach_arrow_acquisition", () -> AzaleaAndArrowGameTests::acquisition); + tests.register("reach_arrows", () -> AzaleaAndArrowGameTests::arrows); + tests.register("kiln", () -> KilnGameTests::cooking); + tests.register("kiln_inventory", () -> KilnGameTests::inventory); + tests.register("kiln_villages", () -> KilnGameTests::villages); + tests.register("upstream_integration", () -> UpstreamIntegrationGameTests::run); + tests.register("cobweb_timers", () -> GameplayGameTests::cobwebTimers); + tests.register("cobweb_tick_event", () -> GameplayGameTests::cobwebTickEvent); + tests.register("melting", () -> GameplayGameTests::melting); + tests.register("melting_table", () -> EnchantmentTableGameTests::melting); + tests.register("skeleton_spawns", () -> SkeletonAndFarmlandGameTests::skeletonSpawns); + tests.register("skeleton_melee", () -> SkeletonAndFarmlandGameTests::skeletonMelee); + tests.register("farmland_protection", () -> SkeletonAndFarmlandGameTests::farmland); + tests.register("creative_tab", () -> SkeletonAndFarmlandGameTests::creativeTab); + tests.register("inspection_blocks", () -> BookInspectionGameTests::blocks); + tests.register("inspection_interactions", () -> BookInspectionGameTests::interactions); + tests.register("inspection_sulfur", () -> BookInspectionGameTests::sulfur); + tests.register(bus); + } + private static void check(GameTestHelper h, boolean ok, String message) { + h.assertTrue(ok, Component.literal(message)); + } + + private static void woolRecipe(GameTestHelper h) { + var level = h.getLevel(); + var recipe = WoolToStringRecipe.INSTANCE; + var shears = new ItemStack(Items.SHEARS); + shears.set(DataComponents.CUSTOM_NAME, Component.literal("Test shears")); + for (var wool : level.registryAccess().lookupOrThrow(Registries.ITEM).getOrThrow(ItemTags.WOOL)) { + for (int woolSlot = 0; woolSlot < 4; woolSlot++) { + var stacks = new ArrayList<>(List.of(ItemStack.EMPTY, ItemStack.EMPTY, ItemStack.EMPTY, ItemStack.EMPTY)); + stacks.set(woolSlot, new ItemStack(wool)); + stacks.set((woolSlot + 1) % 4, shears.copy()); + var input = CraftingInput.of(2, 2, stacks); + var found = level.recipeAccess().getRecipeFor(RecipeType.CRAFTING, input, level); + check(h, found.isPresent() && found.get().value() instanceof WoolToStringRecipe, "All wool colors and slot orders must match registered recipe"); + check(h, recipe.assemble(input).is(Items.STRING) && recipe.assemble(input).getCount() == 2, "One wool must give two string"); + var remainder = recipe.remainingItems(input, level).stream().filter(s -> !s.isEmpty()).findFirst().orElseThrow(); + check(h, remainder.getDamageValue() == 1 && remainder.getHoverName().getString().equals("Test shears"), "Shears must retain data and take one damage"); + check(h, shears.getDamageValue() == 0, "Crafting must not mutate ingredient during preview"); + } + } + check(h, !recipe.matches(CraftingInput.of(2, 2, List.of(new ItemStack(Items.WOOL.white()), shears, new ItemStack(Items.DIRT), ItemStack.EMPTY)), level), "Extra ingredients must fail"); + check(h, !recipe.matches(CraftingInput.of(2, 1, List.of(new ItemStack(Items.WOOL.white()), new ItemStack(Items.STRING))), level), "Wrong tool must fail"); + var broken = shears.copy(); broken.setDamageValue(broken.getMaxDamage() - 1); + check(h, recipe.remainingItems(CraftingInput.of(2, 1, List.of(new ItemStack(Items.WOOL.white()), broken)), level).stream().allMatch(ItemStack::isEmpty), "Last durability must break the shears"); + var enchanted = shears.copy(); + var unbreaking = level.registryAccess().lookupOrThrow(Registries.ENCHANTMENT).getOrThrow(Enchantments.UNBREAKING); + enchanted.enchant(unbreaking, 3); + int damage = 0; + for (int i = 0; i < 256; i++) { + var remainder = recipe.remainingItems(CraftingInput.of(2, 1, List.of(new ItemStack(Items.WOOL.white()), enchanted)), level).get(1); + check(h, remainder.getEnchantments().getLevel(unbreaking) == 3, "Unbreaking must survive crafting"); + damage += remainder.getDamageValue(); + } + check(h, damage > 0 && damage < 160, "Unbreaking III must probabilistically reduce crafting damage"); + var player = (ServerPlayer) h.makeMockServerPlayer(GameType.SURVIVAL); + var connection = new net.minecraft.network.Connection(net.minecraft.network.protocol.PacketFlow.SERVERBOUND); + new io.netty.channel.embedded.EmbeddedChannel(connection); + level.getServer().getPlayerList().placeNewPlayer(connection, player, + net.minecraft.server.network.CommonListenerCookie.createInitial(player.getGameProfile(), false)); + var menu = new CraftingMenu(0, player.getInventory(), ContainerLevelAccess.create(level, h.absolutePos(new BlockPos(2, 1, 2)))); + menu.getSlot(1).set(new ItemStack(Items.WOOL.white(), 3)); + menu.getSlot(2).set(shears.copy()); + // Invoke the real result-slot path twice, including CommonHooks crafting-player context. + for (int i = 0; i < 2; i++) { + var result = menu.getSlot(0).remove(2); + check(h, result.is(Items.STRING) && result.getCount() == 2, "Crafting menu must offer the registered output"); + menu.getSlot(0).onTake(player, result); + } + check(h, menu.getSlot(1).getItem().getCount() == 1 && menu.getSlot(2).getItem().getDamageValue() == 2, "Repeated crafts must consume one wool and one durability each"); + menu.getSlot(1).set(new ItemStack(Items.WOOL.white(), 3)); + for (int i = 0; i < 3; i++) menu.quickMoveStack(player, 0); + check(h, menu.getSlot(1).getItem().isEmpty() && menu.getSlot(2).getItem().getDamageValue() == 5, + "Shift-click crafts must return shears and charge durability for every wool"); + check(h, player.getInventory().countItem(Items.STRING) == 6, "Shift-click must transfer all six string"); + h.succeed(); + } + + private static void crafterShears(GameTestHelper h) { + var pos = new BlockPos(3, 2, 3); + h.setBlock(pos, Blocks.CRAFTER); + var crafter = (CrafterBlockEntity) h.getLevel().getBlockEntity(h.absolutePos(pos)); + crafter.setItem(0, new ItemStack(Items.WOOL.white())); + crafter.setItem(1, new ItemStack(Items.SHEARS)); + h.setBlock(pos.below(), Blocks.REDSTONE_BLOCK); + h.runAfterDelay(10, () -> { + var drops = h.getLevel().getEntitiesOfClass(ItemEntity.class, new AABB(h.absolutePos(pos)).inflate(4)); + check(h, drops.stream().anyMatch(e -> e.getItem().is(Items.STRING) && e.getItem().getCount() == 2), "Crafter must eject two string"); + check(h, drops.stream().anyMatch(e -> e.getItem().is(Items.SHEARS) && e.getItem().getDamageValue() == 1), "Crafter must eject damaged shears using server durability rules"); + h.succeed(); + }); + } + + private static void fluidEffects(GameTestHelper h) { + for (int x = 1; x <= 3; x++) for (int y = 1; y <= 4; y++) for (int z = 1; z <= 3; z++) h.setBlock(x, y, z, Blocks.WATER); + for (int x = 5; x <= 6; x++) for (int y = 1; y <= 4; y++) for (int z = 1; z <= 3; z++) h.setBlock(x, y, z, Blocks.LAVA); + var pig = h.spawn(EntityTypes.PIG, 2, 2, 2); pig.setNoAi(true); pig.setNoGravity(true); + var lavaPig = h.spawn(EntityTypes.PIG, 5, 2, 2); lavaPig.setNoAi(true); lavaPig.setNoGravity(true); lavaPig.setInvulnerable(true); + pig.addEffect(new MobEffectInstance(ModEffects.SINK, 200)); + pig.addEffect(new MobEffectInstance(ModEffects.CHOKE, 200)); + lavaPig.addEffect(new MobEffectInstance(ModEffects.SINK, 200)); + h.runAfterDelay(3, () -> { + double y = pig.getY(); pig.move(MoverType.SELF, new Vec3(0, 0.25, 0)); + check(h, pig.getY() == y, "Sink must stop actual upward water movement"); + double lavaY = lavaPig.getY(); lavaPig.move(MoverType.SELF, new Vec3(0, 0.25, 0)); + check(h, lavaPig.getY() == lavaY, "Sink must also stop lava buoyancy"); + pig.move(MoverType.SELF, new Vec3(0.05, -0.05, 0)); + check(h, pig.getY() < y, "Sink must allow downward and horizontal motion"); + pig.setAirSupply(200); CommonHooks.onLivingBreathe(pig, h.getLevel(), 1, 4); + check(h, pig.getAirSupply() == 198, "Choke I must consume two air per normal breathing tick"); + pig.addEffect(new MobEffectInstance(ModEffects.CHOKE, 200, 1)); + pig.setAirSupply(200); CommonHooks.onLivingBreathe(pig, h.getLevel(), 1, 4); + check(h, pig.getAirSupply() == 197, "Choke II must consume three air"); + pig.setAirSupply(200); CommonHooks.onLivingBreathe(pig, h.getLevel(), 0, 4); + check(h, pig.getAirSupply() == 200, "Respiration's skipped consumption must remain skipped"); + pig.addEffect(new MobEffectInstance(MobEffects.WATER_BREATHING, 200)); + CommonHooks.onLivingBreathe(pig, h.getLevel(), 1, 4); + check(h, pig.getAirSupply() == 200, "Water breathing must continue to protect oxygen"); + pig.removeEffect(ModEffects.SINK); double before = pig.getY(); pig.move(MoverType.SELF, new Vec3(0, 0.1, 0)); + check(h, pig.getY() > before, "Removing Sink must restore upward movement"); + h.succeed(); + }); + } + + private static void moveWeb(Entity entity, int ticks, boolean falling) { + for (int i = 0; i < ticks; i++) { + entity.setPos(entity.getX() + (falling ? 0 : (i % 2 == 0 ? 0.001 : -0.001)), entity.getY() - (falling ? 0.001 : 0), entity.getZ()); + CobwebBreaking.tick(entity); + } + } + private static void cobwebTimers(GameTestHelper h) { + var pos = new BlockPos(3, 2, 3); + h.setBlock(pos, Blocks.COBWEB); + var pig = h.spawn(EntityTypes.PIG, 3.5F, 2.3F, 3.5F); pig.setNoAi(true); pig.setNoGravity(true); pig.setOnGround(true); + CobwebBreaking.tick(pig); moveWeb(pig, 29, false); + h.assertBlockPresent(Blocks.COBWEB, pos); + CobwebBreaking.tick(pig); // No displacement resets the counter. + moveWeb(pig, 29, false); h.assertBlockPresent(Blocks.COBWEB, pos); + moveWeb(pig, 1, false); h.assertBlockPresent(Blocks.AIR, pos); + h.setBlock(pos, Blocks.COBWEB); pig.setOnGround(false); + moveWeb(pig, 159, true); h.assertBlockPresent(Blocks.COBWEB, pos); + moveWeb(pig, 1, true); h.assertBlockPresent(Blocks.AIR, pos); + h.setBlock(pos, Blocks.COBWEB); + var spider = h.spawn(EntityTypes.SPIDER, 3.5F, 2.3F, 3.5F); + var caveSpider = h.spawn(EntityTypes.CAVE_SPIDER, 3.5F, 2.3F, 3.5F); + for (var entity : List.of(spider, caveSpider)) { CobwebBreaking.tick(entity); moveWeb(entity, 200, false); } + h.assertBlockPresent(Blocks.COBWEB, pos); + for (var mode : List.of(GameType.SPECTATOR, GameType.CREATIVE)) { + var player = h.makeMockPlayer(mode); player.getAbilities().flying = true; + player.setPos(pig.position()); CobwebBreaking.tick(player); moveWeb(player, 200, false); + h.assertBlockPresent(Blocks.COBWEB, pos); + } + // Counter belongs to the touched block, not a global web timer. + pig.setOnGround(true); CobwebBreaking.tick(pig); moveWeb(pig, 20, false); + pig.setPos(h.absoluteVec(new Vec3(6.5, 2.3, 3.5))); CobwebBreaking.tick(pig); + pig.setPos(h.absoluteVec(new Vec3(3.5, 2.3, 3.5))); CobwebBreaking.tick(pig); + moveWeb(pig, 29, false); h.assertBlockPresent(Blocks.COBWEB, pos); + moveWeb(pig, 1, false); h.assertBlockPresent(Blocks.AIR, pos); + h.succeed(); + } + + private static void cobwebTickEvent(GameTestHelper h) { + var pos = new BlockPos(3, 2, 3); h.setBlock(pos, Blocks.COBWEB); + var pig = h.spawn(EntityTypes.PIG, 3.5F, 2.3F, 3.5F); pig.setNoAi(true); pig.setNoGravity(true); + // Actual entity tick events must drive the timer, even with no explicit calls to the handler. + for (int i = 1; i <= 35; i++) { + final int tick = i; + h.runAfterDelay(i, () -> pig.setPos(pig.getX() + (tick % 2 == 0 ? 0.001 : -0.001), pig.getY(), pig.getZ())); + } + h.runAfterDelay(37, () -> { h.assertBlockPresent(Blocks.AIR, pos); h.succeed(); }); + } + + private static BlockDropsEvent drops(GameTestHelper h, ServerPlayer player, ItemStack tool, List stacks) { + var entities = new ArrayList(); + for (var stack : stacks) entities.add(new ItemEntity(h.getLevel(), 0, 0, 0, stack)); + var event = new BlockDropsEvent(h.getLevel(), h.absolutePos(new BlockPos(3, 1, 3)), Blocks.IRON_ORE.defaultBlockState(), null, entities, player, tool); + NeoForge.EVENT_BUS.post(event); + return event; + } + private static int count(BlockDropsEvent event, net.minecraft.world.item.Item item) { + return event.getDrops().stream().map(ItemEntity::getItem).filter(s -> s.is(item)).mapToInt(ItemStack::getCount).sum(); + } + private static void melting(GameTestHelper h) { + var level = h.getLevel(); + var player = (ServerPlayer) h.makeMockServerPlayer(GameType.SURVIVAL); + var registry = level.registryAccess().lookupOrThrow(Registries.ENCHANTMENT); + var tool = new ItemStack(Items.DIAMOND_PICKAXE); tool.enchant(registry.getOrThrow(MeltingEnchantment.MELTING), 1); + player.setExperienceLevels(0); player.setExperiencePoints(2); player.totalExperience = 9999; + var event = drops(h, player, tool, List.of(new ItemStack(Items.RAW_IRON, 3))); + check(h, count(event, Items.RAW_IRON) == 3 && MeltingEnchantment.availableExperience(player) == 2, "Insufficient current XP must preserve entire drop; lifetime total is not fuel"); + player.setExperiencePoints(5); + event = drops(h, player, tool, List.of(new ItemStack(Items.RAW_IRON, 3), new ItemStack(Items.DIAMOND, 2))); + check(h, count(event, Items.IRON_INGOT) == 3 && count(event, Items.DIAMOND) == 2 && MeltingEnchantment.availableExperience(player) == 2, "Melt only smeltable drops and charge one point per input"); + var silk = tool.copy(); silk.enchant(registry.getOrThrow(Enchantments.SILK_TOUCH), 1); + event = drops(h, player, silk, List.of(new ItemStack(Items.IRON_ORE))); + check(h, count(event, Items.IRON_ORE) == 1 && MeltingEnchantment.availableExperience(player) == 2, "Silk Touch must take precedence without XP use"); + player.setExperienceLevels(1); player.setExperiencePoints(0); + event = drops(h, player, tool, List.of(new ItemStack(Items.RAW_IRON))); + check(h, count(event, Items.IRON_INGOT) == 1 && player.experienceLevel == 0 && MeltingEnchantment.availableExperience(player) == 6, "Spend exactly one point across level boundary"); + var fortune = tool.copy(); fortune.enchant(registry.getOrThrow(Enchantments.FORTUNE), 3); + player.setExperienceLevels(10); player.setExperiencePoints(0); + var loot = Block.getDrops(Blocks.IRON_ORE.defaultBlockState(), level, h.absolutePos(new BlockPos(3, 1, 3)), null, player, fortune); + int inputCount = loot.stream().filter(s -> s.is(Items.RAW_IRON)).mapToInt(ItemStack::getCount).sum(); + long before = MeltingEnchantment.availableExperience(player); + event = drops(h, player, fortune, loot); + check(h, inputCount > 0 && count(event, Items.IRON_INGOT) == inputCount && MeltingEnchantment.availableExperience(player) == before - inputCount, "Fortune loot must be determined first and fully charged"); + for (int currentLevel : new int[]{16, 17, 30, 31, 32}) { + player.setExperienceLevels(currentLevel); player.setExperiencePoints(0); before = MeltingEnchantment.availableExperience(player); + event = drops(h, player, tool, List.of(new ItemStack(Items.RAW_IRON))); + check(h, count(event, Items.IRON_INGOT) == 1 && MeltingEnchantment.availableExperience(player) == before - 1, "XP formula at level " + currentLevel); + } + // Exercise vanilla block dropping, rather than only posting the event directly. + var pos = h.absolutePos(new BlockPos(5, 2, 5)); before = MeltingEnchantment.availableExperience(player); + Block.dropResources(Blocks.IRON_ORE.defaultBlockState(), level, pos, null, player, tool); + check(h, MeltingEnchantment.availableExperience(player) == before - 1 + && level.getEntitiesOfClass(ItemEntity.class, new AABB(pos).inflate(1)).stream().anyMatch(e -> e.getItem().is(Items.IRON_INGOT)), + "Vanilla block loot path must invoke Melting"); + h.succeed(); + } +} diff --git a/src/verification/java/org/polaris2023/wildwind/hfas/test/KilnGameTests.java b/src/verification/java/org/polaris2023/wildwind/hfas/test/KilnGameTests.java new file mode 100644 index 0000000..d0abbf2 --- /dev/null +++ b/src/verification/java/org/polaris2023/wildwind/hfas/test/KilnGameTests.java @@ -0,0 +1,230 @@ +package org.polaris2023.wildwind.hfas.test; + +import java.util.List; +import java.util.Arrays; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.component.DataComponents; +import net.minecraft.core.registries.Registries; +import net.minecraft.advancements.predicates.ItemPredicate; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.LockCode; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.ExperienceOrb; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.level.GameType; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.HopperBlock; +import net.minecraft.world.level.block.Rotation; +import net.minecraft.world.level.block.entity.HopperBlockEntity; +import net.minecraft.world.level.levelgen.structure.pools.StructurePoolElement; +import net.minecraft.world.level.levelgen.structure.pools.StructureTemplatePool; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings; +import net.minecraft.world.level.levelgen.structure.templatesystem.LiquidSettings; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.Vec3; +import org.polaris2023.wildwind.core.worldgen.MasonKilnProcessor; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.network.chat.Component; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.block.AbstractFurnaceBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import org.polaris2023.wildwind.core.block.entity.KilnBlockEntity; +import org.polaris2023.wildwind.core.recipe.KilnRecipes; + +final class KilnGameTests { + private KilnGameTests() {} + + private static void check(GameTestHelper h, boolean ok, String message) { + h.assertTrue(ok, Component.literal(message)); + } + + static void cooking(GameTestHelper h) { + var pos = h.absolutePos(new net.minecraft.core.BlockPos(2, 1, 2)); + h.setBlock(2, 1, 2, org.polaris2023.wildwind.core.block.ModBlocks.KILN.get()); + BlockEntity raw = h.getLevel().getBlockEntity(pos); + check(h, raw instanceof KilnBlockEntity, "Kiln must create its block entity"); + var kiln = (KilnBlockEntity) raw; + var state = kiln.getBlockState(); + check(h, state.getDestroySpeed(h.getLevel(), pos) == 3.5F && org.polaris2023.wildwind.core.block.ModBlocks.KILN.get().getExplosionResistance() == 3.5F, + "Kiln hardness and blast resistance must both be 3.5"); + check(h, state.getPistonPushReaction() == net.minecraft.world.level.material.PushReaction.BLOCK + && state.isRedstoneConductor(h.getLevel(), pos) && state.isSuffocating(h.getLevel(), pos), + "Kiln must be a solid conductor that pistons cannot move"); + var recipeInput = net.minecraft.world.item.crafting.CraftingInput.of(3, 3, List.of( + ItemStack.EMPTY, new ItemStack(Items.BRICK), ItemStack.EMPTY, + new ItemStack(Items.BRICK), new ItemStack(Items.FURNACE), new ItemStack(Items.BRICK), + new ItemStack(Items.PACKED_MUD), new ItemStack(Items.PACKED_MUD), new ItemStack(Items.PACKED_MUD))); + check(h, h.getLevel().recipeAccess().getRecipeFor(net.minecraft.world.item.crafting.RecipeType.CRAFTING, recipeInput, h.getLevel()) + .orElseThrow().value().assemble(recipeInput).is(org.polaris2023.wildwind.core.block.ModBlocks.KILN.get().asItem()), "Requested kiln crafting pattern must work"); + kiln.setItem(0, new ItemStack(Items.CACTUS, 2)); + kiln.setItem(1, new ItemStack(Items.COAL)); + check(h, KilnRecipes.find(h.getLevel(), kiln.getItem(0)).isPresent(), "Cactus must be kiln-smeltable"); + check(h, KilnRecipes.find(h.getLevel(), new ItemStack(Items.IRON_ORE)).isEmpty(), "Ore must be excluded"); + for (var denied : List.of(Items.RAW_IRON, Items.IRON_PICKAXE, Items.GOLDEN_CHESTPLATE, Items.ANCIENT_DEBRIS)) { + check(h, KilnRecipes.find(h.getLevel(), new ItemStack(denied)).isEmpty(), "Metal/mineral must be excluded: " + denied); + check(h, !kiln.canPlaceItem(0, new ItemStack(denied)), "Automated input must reject excluded materials"); + } + for (var allowed : List.of(Items.SAND, Items.CLAY_BALL, Items.COBBLESTONE, Items.OAK_LOG, Items.WET_SPONGE, Items.POTATO)) { + check(h, KilnRecipes.find(h.getLevel(), new ItemStack(allowed)).isPresent(), "Non-mineral smelting recipe must work: " + allowed); + } + tick(h, kiln, 99); + check(h, kiln.getItem(2).isEmpty(), "Nothing may finish before tick 100"); + var ticker = org.polaris2023.wildwind.core.block.ModBlocks.KILN.get().getTicker(h.getLevel(), state, + org.polaris2023.wildwind.core.block.entity.ModBlockEntities.KILN.get()); + check(h, ticker != null, "Kiln must have a registered server ticker"); + ticker.tick(h.getLevel(), pos, h.getLevel().getBlockState(pos), kiln); + check(h, kiln.getItem(0).getCount() == 1, "Kiln must consume exactly one input after 100 ticks"); + check(h, kiln.getItem(2).is(Items.DYE.green()) && kiln.getItem(2).getCount() == 1, + "Kiln must produce one cactus green dye"); + check(h, kiln.getItem(1).isEmpty(), "One coal must be consumed when the kiln starts"); + check(h, h.getLevel().getBlockState(pos).getValue(AbstractFurnaceBlock.LIT), + "Kiln must be lit while its fuel remains"); + check(h, h.getLevel().getBlockState(pos).getLightEmission() == 13, "Burning kiln must emit light 13"); + var saved = kiln.saveWithFullMetadata(h.getLevel().registryAccess()); + var loaded = (KilnBlockEntity) BlockEntity.loadStatic(pos, kiln.getBlockState(), saved, h.getLevel().registryAccess()); + check(h, loaded != null && loaded.getItem(2).is(Items.DYE.green()), "Contents must survive reload"); + loaded.setLevel(h.getLevel()); + tick(h, loaded, 100); + check(h, loaded.getItem(2).getCount() == 2 && loaded.getItem(0).isEmpty(), "Fuel/progress must continue after reload"); + kiln.setItem(0, new ItemStack(Items.CACTUS)); + kiln.setItem(2, new ItemStack(Items.DYE.green(), 64)); + tick(h, kiln, 100); + check(h, kiln.getItem(0).getCount() == 1 && kiln.getItem(2).getCount() == 64, "Full output must prevent consumption"); + kiln.setItem(2, new ItemStack(Items.STONE)); + tick(h, kiln, 100); + check(h, kiln.getItem(0).getCount() == 1 && kiln.getItem(2).is(Items.STONE), "Different output must prevent cooking"); + kiln.setItem(0, new ItemStack(Items.IRON_ORE)); + kiln.setItem(2, ItemStack.EMPTY); + tick(h, kiln, 100); + check(h, kiln.getItem(2).isEmpty() && kiln.getItem(0).is(Items.IRON_ORE), "Forced excluded input must not cook"); + kiln.setItem(0, new ItemStack(Items.WET_SPONGE)); + kiln.setItem(1, new ItemStack(Items.BUCKET)); + tick(h, kiln, 100); + check(h, kiln.getItem(2).is(Items.SPONGE) && kiln.getItem(1).is(Items.WATER_BUCKET), "Wet sponge must fill the fuel-slot bucket"); + var longFuel = kiln.saveWithFullMetadata(h.getLevel().registryAccess()); + longFuel.putInt("lit_time_remaining", 50000); + longFuel.putInt("lit_total_time", 50000); + var longBurn = (KilnBlockEntity) BlockEntity.loadStatic(pos, kiln.getBlockState(), longFuel, h.getLevel().registryAccess()); + longBurn.setLevel(h.getLevel()); + tick(h, longBurn, 1); + check(h, longBurn.saveCustomOnly(h.getLevel().registryAccess()).getIntOr("lit_time_remaining", 0) == 49999, + "Long modded fuel timers must not be truncated by network short scaling"); + h.succeed(); + } + + private static void tick(GameTestHelper h, KilnBlockEntity kiln, int ticks) { + for (int i = 0; i < ticks; i++) KilnBlockEntity.tick(h.getLevel(), kiln.getBlockPos(), h.getLevel().getBlockState(kiln.getBlockPos()), kiln); + } + + static void inventory(GameTestHelper h) { + var level = h.getLevel(); + var pos = h.absolutePos(new BlockPos(3, 2, 3)); + h.setBlock(3, 2, 3, org.polaris2023.wildwind.core.block.ModBlocks.KILN.get()); + var kiln = (KilnBlockEntity) level.getBlockEntity(pos); + check(h, Arrays.equals(kiln.getSlotsForFace(Direction.UP), new int[]{0}) + && Arrays.equals(kiln.getSlotsForFace(Direction.DOWN), new int[]{2, 1}) + && Arrays.equals(kiln.getSlotsForFace(Direction.EAST), new int[]{1}), "Sided slots must match the specification"); + h.setBlock(3, 3, 3, Blocks.HOPPER); + var top = (HopperBlockEntity) level.getBlockEntity(pos.above()); + top.setItem(0, new ItemStack(Items.CACTUS)); + HopperBlockEntity.pushItemsTick(level, top.getBlockPos(), top.getBlockState(), top); + check(h, kiln.getItem(0).is(Items.CACTUS), "Top hopper must insert ingredients"); + h.setBlock(4, 2, 3, Blocks.HOPPER.defaultBlockState().setValue(HopperBlock.FACING, Direction.WEST)); + var side = (HopperBlockEntity) level.getBlockEntity(pos.east()); + side.setItem(0, new ItemStack(Items.LAVA_BUCKET)); + HopperBlockEntity.pushItemsTick(level, side.getBlockPos(), side.getBlockState(), side); + check(h, kiln.getItem(1).is(Items.LAVA_BUCKET), "Side hopper must insert fuel"); + tick(h, kiln, 100); + check(h, kiln.getItem(1).is(Items.BUCKET), "Lava fuel must return an empty bucket"); + h.setBlock(3, 1, 3, Blocks.HOPPER); + var bottom = (HopperBlockEntity) level.getBlockEntity(pos.below()); + check(h, HopperBlockEntity.suckInItems(level, bottom), "Bottom hopper must pull output"); + check(h, bottom.getItem(0).is(Items.DYE.green()) && kiln.getItem(1).is(Items.BUCKET), "Output must be pulled before the bucket"); + check(h, HopperBlockEntity.suckInItems(level, bottom) && kiln.getItem(1).isEmpty(), "Bottom hopper must next pull the bucket"); + check(h, kiln.saveCustomOnly(level.registryAccess()).getCompound("RecipesUsed").orElseThrow().size() > 0, + "Hopper extraction must retain stored experience"); + kiln.clearContent(); + check(h, AbstractContainerMenu.getRedstoneSignalFromBlockEntity(kiln) == 0, "Empty kiln comparator must be zero"); + kiln.setItem(0, new ItemStack(Items.CACTUS, 64)); + kiln.setItem(1, new ItemStack(Items.COAL, 64)); + kiln.setItem(2, new ItemStack(Items.DYE.green(), 64)); + check(h, kiln.getBlockState().getAnalogOutputSignal(level, pos, Direction.NORTH) == 15, "Comparator must count all three slots"); + kiln.clearContent(); + var player = connectedPlayer(h); + var named = new ItemStack(org.polaris2023.wildwind.core.block.ModBlocks.KILN.get()); + named.set(DataComponents.CUSTOM_NAME, Component.literal("Test kiln")); + named.set(DataComponents.LOCK, new LockCode(ItemPredicate.Builder.item() + .of(level.registryAccess().lookupOrThrow(Registries.ITEM), Items.BRICK).build())); + kiln.applyComponentsFromItemStack(named); + check(h, kiln.getName().getString().equals("Test kiln") && !kiln.canOpen(player), "Custom name and lock must apply"); + player.setItemInHand(InteractionHand.MAIN_HAND, new ItemStack(Items.BRICK)); + check(h, kiln.canOpen(player), "Matching key item must unlock kiln"); + var menu = kiln.createMenu(1, player.getInventory(), player); + check(h, menu != null && !menu.getSlot(0).mayPlace(new ItemStack(Items.IRON_ORE)), "GUI must reject excluded input"); + check(h, !menu.getSlot(2).mayPlace(new ItemStack(Items.STONE)), "Output slot must reject insertion"); + kiln.setItem(0, new ItemStack(Items.CACTUS)); + tick(h, kiln, 100); + var outputSlot = menu.getSlot(2); + var result = outputSlot.remove(1); + outputSlot.onTake(player, result); + check(h, kiln.saveCustomOnly(level.registryAccess()).getCompound("RecipesUsed").orElseThrow().isEmpty(), + "Manual extraction must release and clear stored experience"); + check(h, !level.getEntitiesOfClass(ExperienceOrb.class, new AABB(player.blockPosition()).inflate(2)).isEmpty(), "Manual extraction must spawn stored experience"); + kiln.setItem(0, new ItemStack(Items.CACTUS)); + tick(h, kiln, 100); + var state = kiln.getBlockState(); + check(h, Block.getDrops(state, level, pos, kiln, player, new ItemStack(Items.WOODEN_PICKAXE)).stream() + .anyMatch(stack -> stack.is(org.polaris2023.wildwind.core.block.ModBlocks.KILN.get().asItem())), "Wooden pickaxe must allow kiln loot"); + check(h, !player.hasCorrectToolForDrops(state), "A held brick must not qualify for kiln drops"); + player.setItemInHand(InteractionHand.MAIN_HAND, new ItemStack(Items.WOODEN_PICKAXE)); + check(h, player.hasCorrectToolForDrops(state), "Wooden pickaxe must qualify for kiln drops"); + level.destroyBlock(pos, true, player); + var dropped = level.getEntitiesOfClass(ItemEntity.class, new AABB(pos).inflate(2)); + check(h, dropped.stream().anyMatch(e -> e.getItem().is(org.polaris2023.wildwind.core.block.ModBlocks.KILN.get().asItem())) + && dropped.stream().anyMatch(e -> e.getItem().is(Items.DYE.green())), "Breaking must drop the kiln and its inventory"); + check(h, !level.getEntitiesOfClass(ExperienceOrb.class, new AABB(pos).inflate(2)).isEmpty(), "Breaking must release stored experience"); + h.succeed(); + } + + private static ServerPlayer connectedPlayer(GameTestHelper h) { + var player = (ServerPlayer) h.makeMockServerPlayer(GameType.SURVIVAL); + var connection = new net.minecraft.network.Connection(net.minecraft.network.protocol.PacketFlow.SERVERBOUND); + new io.netty.channel.embedded.EmbeddedChannel(connection); + h.getLevel().getServer().getPlayerList().placeNewPlayer(connection, player, + net.minecraft.server.network.CommonListenerCookie.createInitial(player.getGameProfile(), false)); + player.setPos(h.absoluteVec(new Vec3(6.5, 2, 6.5))); + return player; + } + + static void villages(GameTestHelper h) { + var level = h.getLevel(); + var templates = level.getStructureManager(); + int index = 0; + for (var house : MasonKilnProcessor.HOUSES.entrySet()) { + for (var rotation : Rotation.values()) { + var origin = h.absolutePos(new BlockPos(30 + index++ * 20, 3, 30)); + var template = templates.getOrCreate(house.getKey()); + var settings = new StructurePlaceSettings().setRotation(rotation); + var box = template.getBoundingBox(settings, origin); + var pool = StructurePoolElement.legacy(house.getKey().toString()).apply(StructureTemplatePool.Projection.RIGID); + check(h, pool.place(templates, level, level.structureManager(), level.getChunkSource().getGenerator(), + origin, origin, rotation, box, level.getRandom(), LiquidSettings.IGNORE_WATERLOGGING, false), + "Mason house must place through the real pool path: " + house.getKey()); + var kilnPos = net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate + .calculateRelativePosition(settings, house.getValue().target()).offset(origin); + check(h, level.getBlockState(kilnPos).is(org.polaris2023.wildwind.core.block.ModBlocks.KILN.get()) && level.getBlockEntity(kilnPos) instanceof KilnBlockEntity, + "Every mason house rotation must contain a functional kiln: " + house.getKey() + " " + rotation); + check(h, level.getBlockState(kilnPos).getValue(AbstractFurnaceBlock.FACING) == rotation.rotate(house.getValue().facing()), + "Kiln facing must rotate with its house"); + for (var cutter : template.filterBlocks(origin, settings, Blocks.STONECUTTER)) { + check(h, level.getBlockState(cutter.pos()).is(Blocks.STONECUTTER), "Mason workstation must be preserved"); + } + } + } + h.succeed(); + } +} diff --git a/src/verification/java/org/polaris2023/wildwind/hfas/test/MuddyPigGameTests.java b/src/verification/java/org/polaris2023/wildwind/hfas/test/MuddyPigGameTests.java new file mode 100644 index 0000000..93b02ec --- /dev/null +++ b/src/verification/java/org/polaris2023/wildwind/hfas/test/MuddyPigGameTests.java @@ -0,0 +1,106 @@ +package org.polaris2023.wildwind.hfas.test; + +import java.util.function.Consumer; +import net.minecraft.core.BlockPos; +import net.minecraft.core.registries.Registries; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.EntitySpawnReason; +import net.minecraft.world.entity.EntityTypes; +import net.minecraft.world.entity.MobCategory; +import net.minecraft.world.entity.SpawnPlacements; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.SpawnEggItem; +import net.minecraft.world.level.biome.Biomes; +import net.minecraft.world.level.block.Blocks; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.fml.common.Mod; +import net.neoforged.neoforge.registries.DeferredRegister; +import org.polaris2023.wildwind.wilderness.registry.ModEntities; +import org.polaris2023.wildwind.structures.test.StructureGameTests; + +@Mod("wild_wind_tests") +public final class MuddyPigGameTests { + public MuddyPigGameTests(IEventBus bus) { + StructureGameTests.register(bus); + GameplayGameTests.register(bus); + DeferredRegister> functions = DeferredRegister.create(Registries.TEST_FUNCTION, "wild_wind_tests"); + functions.register("entity", () -> MuddyPigGameTests::entity); + functions.register("spawning", () -> MuddyPigGameTests::spawning); + functions.register(bus); + } + + private static void check(GameTestHelper helper, boolean condition, String message) { + helper.assertTrue(condition, Component.literal(message)); + } + + private static void entity(GameTestHelper helper) { + var level = helper.getLevel(); + var type = ModEntities.MUDDY_PIG.get(); + var pig = helper.spawn(type, 2, 2, 2); + var partner = helper.spawn(type, 4, 2, 2); + check(helper, pig.getMaxHealth() == 10 && pig.getAttributeValue(Attributes.MOVEMENT_SPEED) == 0.25, + "Muddy pig must receive vanilla pig attributes"); + check(helper, pig.isFood(Items.CARROT.getDefaultInstance()) && !pig.isFood(Items.WHEAT.getDefaultInstance()), + "Muddy pig must use vanilla pig food tag"); + check(helper, SpawnEggItem.getType(org.polaris2023.wildwind.wilderness.registry.ModItems.MUDDY_PIG_SPAWN_EGG.toStack()) == type, + "Spawn egg entity component must point to muddy pig"); + var baby = pig.getBreedOffspring(level, partner); + check(helper, baby != null && baby.getType() == type, "Breeding must create a muddy pig rather than vanilla pig"); + baby.setBaby(true); + check(helper, baby.isBaby(), "Offspring must support baby state"); + pig.setInLove(null); + partner.setInLove(null); + check(helper, pig.canMate(partner) && !pig.canMate(pig), "Two adult muddy pigs must be able to mate"); + var vanilla = helper.spawn(EntityTypes.PIG, 6, 2, 2); + vanilla.setInLove(null); + check(helper, !pig.canMate(vanilla) && !vanilla.canMate(pig), "Vanilla pigs must remain a separate breeding species"); + var eggBaby = SpawnEggItem.spawnOffspringFromSpawnEgg(helper.makeMockServerPlayerInLevel(), pig, + type, level, pig.position(), org.polaris2023.wildwind.wilderness.registry.ModItems.MUDDY_PIG_SPAWN_EGG.toStack()); + check(helper, eggBaby.isPresent() && eggBaby.get().isBaby() && eggBaby.get().getType() == type, + "Using the spawn egg on an adult must create a muddy pig baby"); + check(helper, level.getServer().reloadableRegistries().getLootTable(pig.getLootTable().orElseThrow()) + != net.minecraft.world.level.storage.loot.LootTable.EMPTY, "Muddy pig loot table must be loaded"); + helper.succeed(); + } + + private static void spawning(GameTestHelper helper) { + var level = helper.getLevel(); + var type = ModEntities.MUDDY_PIG.get(); + var biomes = level.registryAccess().lookupOrThrow(Registries.BIOME); + for (var biome : biomes.listElements().toList()) { + var entries = biome.value().getMobSettings().getMobs(MobCategory.CREATURE).unwrap(); + var matches = entries.stream().filter(entry -> entry.value().type() == type).toList(); + boolean expected = biome.is(Biomes.SWAMP) || biome.is(Biomes.MANGROVE_SWAMP); + check(helper, matches.size() == (expected ? 1 : 0), "Biome spawn membership: " + biome.key().identifier()); + if (expected) { + var entry = matches.getFirst(); + check(helper, entry.weight() == 10 && entry.value().minCount() == 2 && entry.value().maxCount() == 4, + "Spawn weight and group bounds must be 10 / 2-4"); + } + } + var pos = new BlockPos(3, 2, 3); + var absolute = helper.absolutePos(pos); + helper.setBlock(pos, Blocks.AIR); + helper.setBlock(pos.above(), Blocks.AIR); + helper.setBlock(pos.above(2), Blocks.GLOWSTONE); + helper.runAfterDelay(5, () -> { + for (var block : new net.minecraft.world.level.block.Block[]{Blocks.GRASS_BLOCK, Blocks.MUD, Blocks.MUDDY_MANGROVE_ROOTS}) { + helper.setBlock(pos.below(), block); + check(helper, SpawnPlacements.isSpawnPositionOk(type, level, absolute) + && SpawnPlacements.checkSpawnRules(type, level, EntitySpawnReason.NATURAL, absolute, level.getRandom()), + "Natural spawning must accept " + block); + } + helper.setBlock(pos.below(), Blocks.STONE); + check(helper, !SpawnPlacements.checkSpawnRules(type, level, EntitySpawnReason.NATURAL, absolute, level.getRandom()), + "Natural spawning must reject stone"); + helper.setBlock(pos.below(), Blocks.MUD); + helper.setBlock(pos, Blocks.WATER); + check(helper, !SpawnPlacements.isSpawnPositionOk(type, level, absolute), "Natural spawning must reject water"); + helper.setBlock(pos, Blocks.STONE); + check(helper, !SpawnPlacements.isSpawnPositionOk(type, level, absolute), "Natural spawning must reject obstructed space"); + helper.succeed(); + }); + } +} diff --git a/src/verification/java/org/polaris2023/wildwind/hfas/test/SkeletonAndFarmlandGameTests.java b/src/verification/java/org/polaris2023/wildwind/hfas/test/SkeletonAndFarmlandGameTests.java new file mode 100644 index 0000000..98964bf --- /dev/null +++ b/src/verification/java/org/polaris2023/wildwind/hfas/test/SkeletonAndFarmlandGameTests.java @@ -0,0 +1,154 @@ +package org.polaris2023.wildwind.hfas.test; + +import java.util.List; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Holder; +import net.minecraft.core.component.DataComponents; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.registries.Registries; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.network.chat.Component; +import net.minecraft.world.effect.MobEffect; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.effect.MobEffects; +import net.minecraft.world.entity.EntitySpawnReason; +import net.minecraft.world.entity.EntityTypes; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.ai.goal.MeleeAttackGoal; +import net.minecraft.world.entity.monster.skeleton.AbstractSkeleton; +import net.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.item.CreativeModeTabs; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.alchemy.PotionContents; +import net.minecraft.world.item.enchantment.Enchantments; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.FarmlandBlock; +import org.polaris2023.wildwind.core.CoreMod; +import org.polaris2023.wildwind.core.registry.ModCreativeTabs; +import org.polaris2023.wildwind.wilderness.registry.ModPotions; + +final class SkeletonAndFarmlandGameTests { + private SkeletonAndFarmlandGameTests() {} + + private static void check(GameTestHelper h, boolean ok, String message) { + h.assertTrue(ok, Component.literal(message)); + } + + static void skeletonSpawns(GameTestHelper h) { + var level = h.getLevel(); + level.getRandom().setSeed(428136L); + for (var type : List.of(EntityTypes.SKELETON, EntityTypes.STRAY, EntityTypes.BOGGED, EntityTypes.PARCHED)) { + int swords = 0; + for (int i = 0; i < 200; i++) { + // Use the real initialization path used by spawn eggs and newly spawned mobs. + var skeleton = type.create(level, null, h.absolutePos(new BlockPos(2, 2, 2)), EntitySpawnReason.NATURAL, false, false); + check(h, skeleton != null, "Skeleton variant must initialize"); + var weapon = skeleton.getMainHandItem(); + check(h, weapon.is(Items.BOW) || weapon.is(Items.STONE_SWORD), "Spawn weapon must be bow or stone sword"); + boolean melee = skeleton.getGoalSelector().getAvailableGoals().stream() + .anyMatch(goal -> goal.getGoal() instanceof MeleeAttackGoal); + check(h, melee == weapon.is(Items.STONE_SWORD), "Weapon must select the matching combat AI"); + if (weapon.is(Items.STONE_SWORD)) swords++; + skeleton.discard(); + } + check(h, swords >= 5 && swords <= 45, "Fixed-seed spawn sample must contain roughly ten percent swords: " + type + " = " + swords); + } + var wither = EntityTypes.WITHER_SKELETON.create(level, null, h.absolutePos(new BlockPos(2, 2, 2)), EntitySpawnReason.NATURAL, false, false); + check(h, wither.getMainHandItem().is(Items.STONE_SWORD), "Wither skeleton must retain its vanilla equipment"); + wither.discard(); + h.succeed(); + } + + static void skeletonMelee(GameTestHelper h) { + checkHit(h, h.spawn(EntityTypes.STRAY, 2, 2, 2), MobEffects.SLOWNESS, 600); + checkHit(h, h.spawn(EntityTypes.BOGGED, 3, 2, 2), MobEffects.POISON, 80); + checkHit(h, h.spawn(EntityTypes.PARCHED, 4, 2, 2), MobEffects.WEAKNESS, 600); + var skeleton = h.spawn(EntityTypes.SKELETON, 5, 2, 2); + skeleton.setNoAi(true); + skeleton.setItemSlot(EquipmentSlot.MAINHAND, new ItemStack(Items.STONE_SWORD)); + var target = h.spawn(EntityTypes.COW, 5, 2, 4); + target.setNoAi(true); + check(h, skeleton.doHurtTarget(h.getLevel(), target) && target.getActiveEffects().isEmpty(), "Normal skeleton melee must not add a special effect"); + h.succeed(); + } + + private static void checkHit(GameTestHelper h, AbstractSkeleton skeleton, Holder effect, int ticks) { + skeleton.setNoAi(true); + skeleton.setItemSlot(EquipmentSlot.MAINHAND, new ItemStack(Items.STONE_SWORD)); + var target = h.spawn(EntityTypes.COW, 2, 2, 5); + target.setNoAi(true); + check(h, skeleton.doHurtTarget(h.getLevel(), target), "Stone sword must successfully damage target"); + var applied = target.getEffect(effect); + check(h, applied != null && applied.getDuration() == ticks && applied.getAmplifier() == 0, + "Melee must apply exactly the requested duration and level"); + var invulnerable = h.spawn(EntityTypes.COW, 3, 2, 5); + invulnerable.setNoAi(true); + invulnerable.setInvulnerable(true); + check(h, !skeleton.doHurtTarget(h.getLevel(), invulnerable) && !invulnerable.hasEffect(effect), + "Failed melee hits must not apply an effect"); + } + + static void farmland(GameTestHelper h) { + var level = h.getLevel(); + var cow = h.spawn(EntityTypes.COW, 2, 2, 2); + cow.setNoAi(true); + var pos = h.absolutePos(new BlockPos(3, 1, 3)); + var farmland = (FarmlandBlock) Blocks.FARMLAND; + var featherFalling = level.registryAccess().lookupOrThrow(Registries.ENCHANTMENT).getOrThrow(Enchantments.FEATHER_FALLING); + var boots = new ItemStack(Items.DIAMOND_BOOTS); + boots.enchant(featherFalling, 1); + cow.setItemSlot(EquipmentSlot.FEET, boots); + level.setBlockAndUpdate(pos, Blocks.FARMLAND.defaultBlockState()); + farmland.fallOn(level, level.getBlockState(pos), pos, cow, 6); + check(h, level.getBlockState(pos).is(Blocks.FARMLAND), "Worn Feather Falling I must protect farmland for non-player entities"); + check(h, cow.getHealth() < cow.getMaxHealth(), "Farmland protection must not cancel remaining fall damage"); + cow.setItemSlot(EquipmentSlot.FEET, ItemStack.EMPTY); + cow.setItemSlot(EquipmentSlot.MAINHAND, boots); + farmland.fallOn(level, level.getBlockState(pos), pos, cow, 6); + check(h, level.getBlockState(pos).is(Blocks.DIRT), "Holding enchanted armor must not protect farmland"); + level.setBlockAndUpdate(pos, Blocks.FARMLAND.defaultBlockState()); + cow.addEffect(new MobEffectInstance(MobEffects.SLOW_FALLING, 200)); + farmland.fallOn(level, level.getBlockState(pos), pos, cow, 6); + check(h, level.getBlockState(pos).is(Blocks.FARMLAND), "Slow Falling must protect farmland without worn armor"); + cow.removeEffect(MobEffects.SLOW_FALLING); + farmland.fallOn(level, level.getBlockState(pos), pos, cow, 6); + check(h, level.getBlockState(pos).is(Blocks.DIRT), "Removing protection must restore trampling"); + h.succeed(); + } + + static void creativeTab(GameTestHelper h) { + var params = new CreativeModeTab.ItemDisplayParameters(h.getLevel().enabledFeatures(), true, h.getLevel().registryAccess()); + var tab = ModCreativeTabs.WILD_WIND.get(); + tab.buildContents(params); + for (var register : List.of(org.polaris2023.wildwind.core.block.ModBlocks.ITEMS, org.polaris2023.wildwind.core.registry.ModItems.ITEMS, org.polaris2023.wildwind.wilderness.block.ModBlocks.ITEMS, org.polaris2023.wildwind.wilderness.registry.ModItems.ITEMS, org.polaris2023.wildwind.barren.block.ModBlocks.ITEMS)) { + for (var item : register.getEntries()) { + check(h, tab.getDisplayItems().stream().filter(stack -> stack.is(item.get())).count() == (item == org.polaris2023.wildwind.wilderness.registry.ModItems.TIPPED_ARROW ? 2 : 1), + "Every registered mod item/arrow variant must appear once in its own tab: " + item.getId()); + } + } + for (var potion : ModPotions.POTIONS.getEntries()) { + for (var item : List.of(Items.POTION, Items.SPLASH_POTION, Items.LINGERING_POTION, Items.TIPPED_ARROW)) { + check(h, tab.contains(org.polaris2023.wildwind.wilderness.arrow.ReachArrows.convert(PotionContents.createItemStack(item, potion))), "Mod tab must include each Reach potion and arrow variant"); + } + } + for (var key : List.of(CreativeModeTabs.BUILDING_BLOCKS, CreativeModeTabs.NATURAL_BLOCKS, + CreativeModeTabs.INGREDIENTS, CreativeModeTabs.SPAWN_EGGS, CreativeModeTabs.FOOD_AND_DRINKS, CreativeModeTabs.COMBAT)) { + var vanilla = BuiltInRegistries.CREATIVE_MODE_TAB.getValueOrThrow(key); + vanilla.buildContents(params); + check(h, vanilla.getDisplayItems().stream().noneMatch(stack -> + org.polaris2023.wildwind.core.api.WildWindModules.owns(BuiltInRegistries.ITEM.getKey(stack.getItem()).getNamespace())), + "Vanilla categories must not contain mod items"); + check(h, vanilla.getDisplayItems().stream().noneMatch(stack -> { + var contents = stack.get(DataComponents.POTION_CONTENTS); + return contents != null && contents.potion().isPresent() + && org.polaris2023.wildwind.core.api.WildWindModules.owns(contents.potion().get().unwrapKey().orElseThrow().identifier().getNamespace()); + }), "Vanilla categories must not duplicate mod potions"); + } + CreativeModeTabs.searchTab().buildContents(params); + check(h, CreativeModeTabs.searchTab().contains(org.polaris2023.wildwind.wilderness.registry.ModItems.MUDDY_PIG_SPAWN_EGG.toStack()) + && CreativeModeTabs.searchTab().contains(PotionContents.createItemStack(Items.POTION, ModPotions.REACH)), + "Global creative search must still discover mod contents"); + h.succeed(); + } +} diff --git a/src/verification/java/org/polaris2023/wildwind/hfas/test/UpstreamIntegrationGameTests.java b/src/verification/java/org/polaris2023/wildwind/hfas/test/UpstreamIntegrationGameTests.java new file mode 100644 index 0000000..1348f5a --- /dev/null +++ b/src/verification/java/org/polaris2023/wildwind/hfas/test/UpstreamIntegrationGameTests.java @@ -0,0 +1,84 @@ +package org.polaris2023.wildwind.hfas.test; + +import java.util.List; +import net.minecraft.core.BlockPos; +import net.minecraft.core.component.DataComponents; +import net.minecraft.core.registries.Registries; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.network.chat.Component; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.crafting.RecipeType; +import net.minecraft.world.item.crafting.SingleRecipeInput; +import net.minecraft.world.level.GameType; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.Vec3; +import org.polaris2023.wildwind.wilderness.component.OmniClawTools; +import org.polaris2023.wildwind.core.enchantment.MeltingEnchantment; +import org.polaris2023.wildwind.wilderness.entity.animal.MudcrabVariant; +import org.polaris2023.wildwind.wilderness.registry.*; + +final class UpstreamIntegrationGameTests { + private UpstreamIntegrationGameTests() {} + + private static void check(GameTestHelper h, boolean ok, String message) { + h.assertTrue(ok, Component.literal(message)); + } + + static void run(GameTestHelper h) { + var level = h.getLevel(); + var crab = h.spawn(ModEntities.MUDCRAB.get(), 2, 2, 2); + crab.setNoAi(true); + check(h, crab.getMaxHealth() == 10 && crab.getVariant() != null, + "Merged mudcrab must spawn with attributes and a registered variant"); + check(h, level.registryAccess().lookupOrThrow(DatadrivenRegistryKey.MUDCRAB_VARIANT).size() == 3, + "All three mudcrab variants must be present"); + crab.setVariant(MudcrabVariant.lookup(level.registryAccess(), MudcrabVariant.WARM)); + check(h, crab.getVariant().is(MudcrabVariant.WARM) + && crab.getBucketItemStack().is(org.polaris2023.wildwind.wilderness.registry.ModItems.MUDCRAB_BUCKET.get()), "Mudcrab variant and bucket must work"); + var fish = h.spawn(ModEntities.PIRANHA.get(), 4, 2, 2); + fish.setNoAi(true); + check(h, fish.getBucketItemStack().is(org.polaris2023.wildwind.wilderness.registry.ModItems.PIRANHA_BUCKET.get()), "Piranha bucket must remain registered"); + var cooking = level.recipeAccess().getRecipeFor(RecipeType.SMELTING, + new SingleRecipeInput(org.polaris2023.wildwind.wilderness.registry.ModItems.PIRANHA.toStack()), level); + check(h, cooking.isPresent() && cooking.get().value().assemble(new SingleRecipeInput(org.polaris2023.wildwind.wilderness.registry.ModItems.PIRANHA.toStack())) + .is(org.polaris2023.wildwind.wilderness.registry.ModItems.COOKED_PIRANHA.get()), "Upstream piranha smelting recipe must load"); + for (var material : org.polaris2023.wildwind.core.registry.ModItems.MATERIALS) { + check(h, !material.toStack().has(DataComponents.FOOD), "The seven local materials must stay ordinary items"); + } + check(h, !ModPotions.REACH.value().getEffects().isEmpty(), "Upstream Reach potion must remain registered"); + + var player = (ServerPlayer) h.makeMockServerPlayer(GameType.SURVIVAL); + var connection = new net.minecraft.network.Connection(net.minecraft.network.protocol.PacketFlow.SERVERBOUND); + new io.netty.channel.embedded.EmbeddedChannel(connection); + level.getServer().getPlayerList().placeNewPlayer(connection, player, + net.minecraft.server.network.CommonListenerCookie.createInitial(player.getGameProfile(), false)); + player.gameMode.changeGameModeForPlayer(GameType.SURVIVAL); + player.setPos(h.absoluteVec(new Vec3(6.5, 2, 6.5))); + player.addEffect(new MobEffectInstance(ModMobEffects.REACH, 200)); + check(h, player.getAttributeValue(ModAttributes.EXTRA_ITEM_PICKUP_RANGE) == 2, + "Upstream Reach attribute must work with merged player code"); + player.removeEffect(ModMobEffects.REACH); + + var pickaxe = new ItemStack(Items.DIAMOND_PICKAXE); + pickaxe.enchant(level.registryAccess().lookupOrThrow(Registries.ENCHANTMENT).getOrThrow(MeltingEnchantment.MELTING), 1); + var claw = org.polaris2023.wildwind.wilderness.registry.ModItems.OMNI_CLAW.toStack(); + claw.set(ModDataComponents.OMNI_CLAW_TOOLS.get(), new OmniClawTools(List.of(pickaxe), 0)); + player.setItemInHand(InteractionHand.MAIN_HAND, claw); + player.setExperienceLevels(1); + player.setExperiencePoints(0); + var pos = new BlockPos(5, 2, 5); + h.setBlock(pos, Blocks.IRON_ORE); + check(h, player.gameMode.destroyBlock(h.absolutePos(pos)), "Omni Claw must break a real block through the player path"); + check(h, MeltingEnchantment.availableExperience(player) == 6, + "Melting on an Omni Claw's internal pickaxe must consume exactly one XP point"); + check(h, level.getEntitiesOfClass(ItemEntity.class, new AABB(h.absolutePos(pos)).inflate(1)).stream() + .anyMatch(e -> e.getItem().is(Items.IRON_INGOT)), "Omni Claw and Melting must produce smelted loot together"); + h.succeed(); + } +} diff --git a/src/verification/java/org/polaris2023/wildwind/structures/test/StructureGameTests.java b/src/verification/java/org/polaris2023/wildwind/structures/test/StructureGameTests.java new file mode 100644 index 0000000..c16527a --- /dev/null +++ b/src/verification/java/org/polaris2023/wildwind/structures/test/StructureGameTests.java @@ -0,0 +1,99 @@ +package org.polaris2023.wildwind.structures.test; + +import java.util.function.Consumer; +import net.minecraft.core.BlockPos; +import net.minecraft.core.HolderSet; +import net.minecraft.core.registries.Registries; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.Identifier; +import net.minecraft.resources.ResourceKey; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.phys.Vec3; +import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceSerializationContext; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.neoforge.registries.DeferredRegister; +import org.polaris2023.wildwind.structures.worldgen.ConfiguredStructure; +import org.polaris2023.wildwind.structures.worldgen.ConfiguredTemplatePiece; +import org.polaris2023.wildwind.structures.worldgen.GeneratedStructureIndex; + +public final class StructureGameTests { + private StructureGameTests() {} + + public static void register(IEventBus bus) { + DeferredRegister> functions = DeferredRegister.create(Registries.TEST_FUNCTION, "wild_wind_tests"); + functions.register("generation", () -> StructureGameTests::generation); + functions.register(bus); + } + + private static void generation(GameTestHelper helper) { + helper.assertTrue(net.neoforged.fml.ModList.get().isLoaded("wild_wind_core") + && !net.neoforged.fml.ModList.get().isLoaded("ww_structures"), + Component.literal("Structures and items must load from the core mod")); + for (var item : org.polaris2023.wildwind.core.registry.ModItems.MATERIALS) { + helper.assertTrue(net.minecraft.core.registries.BuiltInRegistries.ITEM.containsKey(item.getId()) + && item.get().getClass() == net.minecraft.world.item.Item.class + && !item.toStack().has(net.minecraft.core.component.DataComponents.FOOD), + Component.literal("Plain material must be available alongside structures: " + item.getId())); + } + var level = helper.getLevel(); + var id = Identifier.parse("ww_structures:smoke"); + var holder = level.registryAccess().lookupOrThrow(Registries.STRUCTURE).getOrThrow(ResourceKey.create(Registries.STRUCTURE, id)); + helper.assertTrue(holder.value() instanceof ConfiguredStructure, Component.literal("Config must become a registered structure")); + for (String rejected : new String[]{"blocked", "disabled"}) { + var rejectedHolder = level.registryAccess().lookupOrThrow(Registries.STRUCTURE).getOrThrow( + ResourceKey.create(Registries.STRUCTURE, Identifier.parse("ww_structures:" + rejected))); + helper.assertTrue(level.getChunkSource().getGenerator().findNearestMapStructure(level, HolderSet.direct(rejectedHolder), + new BlockPos(2048, 0, 2048), 2, false) == null, Component.literal(rejected + " must not generate")); + } + // Far from the test arena; generate through the actual ChunkGenerator, not /place. + var result = level.getChunkSource().getGenerator().findNearestMapStructure(level, HolderSet.direct(holder), + new BlockPos(2048, 0, 2048), 4, false); + helper.assertTrue(result != null, Component.literal("Native locate must discover the configured structure")); + var pos = result.getFirst(); + var chunk = level.getChunk(pos); + var start = chunk.getStartForStructure(holder.value()); + helper.assertTrue(start != null && start.isValid(), Component.literal("Generated chunk must contain a valid start")); + var piece = (ConfiguredTemplatePiece) start.getPieces().getFirst(); + var box = piece.getBoundingBox(); + helper.assertTrue(box.getXSpan() == 19 && box.getZSpan() == 23, Component.literal("Rotation must swap template footprint")); + BlockPos floor = new BlockPos(box.minX(), box.minY(), box.minZ()); + // Load every intersecting chunk so that the cross-chunk template has been placed completely. + for (int x = box.minX() >> 4; x <= box.maxX() >> 4; x++) { + for (int z = box.minZ() >> 4; z <= box.maxZ() >> 4; z++) level.getChunk(x, z); + } + helper.assertTrue(level.getBlockState(floor).is(Blocks.MOSSY_COBBLESTONE), Component.literal("Template foundation must generate")); + helper.assertTrue(level.getBlockState(floor.above(1)).is(Blocks.STONE_BRICKS), Component.literal("Template pillar must generate")); + for (int x : new int[]{box.minX(), box.maxX()}) { + for (int z : new int[]{box.minZ(), box.maxZ()}) { + helper.assertTrue(level.getBlockState(new BlockPos(x, box.minY(), z)).is(Blocks.MOSSY_COBBLESTONE), + Component.literal("All corners must generate across chunk boundaries")); + helper.assertTrue(level.getBlockState(new BlockPos(x, box.minY() + 1, z)).is(Blocks.STONE_BRICKS), + Component.literal("Rotated pillars must generate across chunk boundaries")); + } + } + var serialization = StructurePieceSerializationContext.fromLevel(level); + CompoundTag saved = piece.createTag(serialization); + var restored = new ConfiguredTemplatePiece(serialization, saved); + helper.assertTrue(restored.templatePosition().equals(piece.templatePosition()) && restored.getRotation() == piece.getRotation(), + Component.literal("Piece origin and rotation must survive chunk NBT round trip")); + helper.runAfterDelay(2, () -> { + var index = level.getDataStorage().computeIfAbsent(GeneratedStructureIndex.TYPE); + helper.assertTrue(index.nearest(id, pos).isPresent(), Component.literal("Full chunk must enter the generated structure index")); + var source = level.getServer().createCommandSourceStack().withLevel(level); + var dispatcher = level.getServer().getCommands().getDispatcher(); + try { + helper.assertTrue(dispatcher.execute("wwstructure locate smoke", source.withPosition(Vec3.atCenterOf(pos))) == 1, + Component.literal("Generated locate command must succeed")); + helper.assertTrue(dispatcher.execute("wwstructure search smoke 2", source.withPosition(Vec3.atCenterOf(pos))) == 1, + Component.literal("Native search command must succeed")); + helper.assertTrue(dispatcher.execute("wwstructure locate missing", source) == 0, + Component.literal("Unknown structure must report no result")); + } catch (com.mojang.brigadier.exceptions.CommandSyntaxException exception) { + throw new IllegalStateException(exception); + } + helper.succeed(); + }); + } +} diff --git a/src/verification/java/org/polaris2023/wildwind/structures/test/mixin/GameTestServerMixin.java b/src/verification/java/org/polaris2023/wildwind/structures/test/mixin/GameTestServerMixin.java new file mode 100644 index 0000000..6b86b94 --- /dev/null +++ b/src/verification/java/org/polaris2023/wildwind/structures/test/mixin/GameTestServerMixin.java @@ -0,0 +1,14 @@ +package org.polaris2023.wildwind.structures.test.mixin; + +import net.minecraft.gametest.framework.GameTestServer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyArg; + +/** Vanilla GameTest disables structure generation. Enable it only in the test mod. */ +@Mixin(GameTestServer.class) +public abstract class GameTestServerMixin { + @ModifyArg(method = "", at = @At(value = "INVOKE", + target = "Lnet/minecraft/world/level/levelgen/WorldOptions;(JZZ)V"), index = 1) + private static boolean structuresTests$enableStructures(boolean original) { return true; } +} diff --git a/src/verification/resources/data/minecraft/worldgen/world_preset/flat.json b/src/verification/resources/data/minecraft/worldgen/world_preset/flat.json new file mode 100644 index 0000000..e53cbdd --- /dev/null +++ b/src/verification/resources/data/minecraft/worldgen/world_preset/flat.json @@ -0,0 +1,21 @@ +{ + "dimensions": { + "minecraft:overworld": { + "type": "minecraft:overworld", + "generator": { + "type": "minecraft:flat", + "settings": { + "biome": "minecraft:plains", + "features": false, + "lakes": false, + "layers": [ + {"block": "minecraft:bedrock", "height": 1}, + {"block": "minecraft:dirt", "height": 2}, + {"block": "minecraft:grass_block", "height": 1} + ], + "structure_overrides": ["ww_structures:smoke", "ww_structures:blocked"] + } + } + } + } +} diff --git a/src/verification/resources/data/wild_wind_tests/structure/empty.nbt b/src/verification/resources/data/wild_wind_tests/structure/empty.nbt new file mode 100644 index 0000000..1b63d36 Binary files /dev/null and b/src/verification/resources/data/wild_wind_tests/structure/empty.nbt differ diff --git a/src/verification/resources/data/wild_wind_tests/test_instance/azalea_shelf.json b/src/verification/resources/data/wild_wind_tests/test_instance/azalea_shelf.json new file mode 100644 index 0000000..eca6cef --- /dev/null +++ b/src/verification/resources/data/wild_wind_tests/test_instance/azalea_shelf.json @@ -0,0 +1,7 @@ +{ + "type": "minecraft:function", + "function": "wild_wind_tests:azalea_shelf", + "environment": "minecraft:default", + "structure": "wild_wind_tests:empty", + "max_ticks": 240 +} diff --git a/src/verification/resources/data/wild_wind_tests/test_instance/azalea_shelf_chain.json b/src/verification/resources/data/wild_wind_tests/test_instance/azalea_shelf_chain.json new file mode 100644 index 0000000..df660b0 --- /dev/null +++ b/src/verification/resources/data/wild_wind_tests/test_instance/azalea_shelf_chain.json @@ -0,0 +1,7 @@ +{ + "type": "minecraft:function", + "function": "wild_wind_tests:azalea_shelf_chain", + "environment": "minecraft:default", + "structure": "wild_wind_tests:empty", + "max_ticks": 240 +} diff --git a/src/verification/resources/data/wild_wind_tests/test_instance/azalea_signs.json b/src/verification/resources/data/wild_wind_tests/test_instance/azalea_signs.json new file mode 100644 index 0000000..2052346 --- /dev/null +++ b/src/verification/resources/data/wild_wind_tests/test_instance/azalea_signs.json @@ -0,0 +1,7 @@ +{ + "type": "minecraft:function", + "function": "wild_wind_tests:azalea_signs", + "environment": "minecraft:default", + "structure": "wild_wind_tests:empty", + "max_ticks": 240 +} diff --git a/src/verification/resources/data/wild_wind_tests/test_instance/cobweb_tick_event.json b/src/verification/resources/data/wild_wind_tests/test_instance/cobweb_tick_event.json new file mode 100644 index 0000000..46a68dc --- /dev/null +++ b/src/verification/resources/data/wild_wind_tests/test_instance/cobweb_tick_event.json @@ -0,0 +1,7 @@ +{ + "type": "minecraft:function", + "function": "wild_wind_tests:cobweb_tick_event", + "environment": "minecraft:default", + "structure": "wild_wind_tests:empty", + "max_ticks": 240 +} diff --git a/src/verification/resources/data/wild_wind_tests/test_instance/cobweb_timers.json b/src/verification/resources/data/wild_wind_tests/test_instance/cobweb_timers.json new file mode 100644 index 0000000..0a49730 --- /dev/null +++ b/src/verification/resources/data/wild_wind_tests/test_instance/cobweb_timers.json @@ -0,0 +1,7 @@ +{ + "type": "minecraft:function", + "function": "wild_wind_tests:cobweb_timers", + "environment": "minecraft:default", + "structure": "wild_wind_tests:empty", + "max_ticks": 240 +} diff --git a/src/verification/resources/data/wild_wind_tests/test_instance/crafter_shears.json b/src/verification/resources/data/wild_wind_tests/test_instance/crafter_shears.json new file mode 100644 index 0000000..20acd51 --- /dev/null +++ b/src/verification/resources/data/wild_wind_tests/test_instance/crafter_shears.json @@ -0,0 +1,7 @@ +{ + "type": "minecraft:function", + "function": "wild_wind_tests:crafter_shears", + "environment": "minecraft:default", + "structure": "wild_wind_tests:empty", + "max_ticks": 240 +} diff --git a/src/verification/resources/data/wild_wind_tests/test_instance/creative_tab.json b/src/verification/resources/data/wild_wind_tests/test_instance/creative_tab.json new file mode 100644 index 0000000..651679a --- /dev/null +++ b/src/verification/resources/data/wild_wind_tests/test_instance/creative_tab.json @@ -0,0 +1,7 @@ +{ + "type": "minecraft:function", + "function": "wild_wind_tests:creative_tab", + "environment": "minecraft:default", + "structure": "wild_wind_tests:empty", + "max_ticks": 240 +} diff --git a/src/verification/resources/data/wild_wind_tests/test_instance/entity.json b/src/verification/resources/data/wild_wind_tests/test_instance/entity.json new file mode 100644 index 0000000..9cc0e61 --- /dev/null +++ b/src/verification/resources/data/wild_wind_tests/test_instance/entity.json @@ -0,0 +1,7 @@ +{ + "type": "minecraft:function", + "function": "wild_wind_tests:entity", + "environment": "minecraft:default", + "structure": "wild_wind_tests:empty", + "max_ticks": 100 +} diff --git a/src/verification/resources/data/wild_wind_tests/test_instance/farmland_protection.json b/src/verification/resources/data/wild_wind_tests/test_instance/farmland_protection.json new file mode 100644 index 0000000..e773bc8 --- /dev/null +++ b/src/verification/resources/data/wild_wind_tests/test_instance/farmland_protection.json @@ -0,0 +1,7 @@ +{ + "type": "minecraft:function", + "function": "wild_wind_tests:farmland_protection", + "environment": "minecraft:default", + "structure": "wild_wind_tests:empty", + "max_ticks": 240 +} diff --git a/src/verification/resources/data/wild_wind_tests/test_instance/fluid_effects.json b/src/verification/resources/data/wild_wind_tests/test_instance/fluid_effects.json new file mode 100644 index 0000000..8f0a0f4 --- /dev/null +++ b/src/verification/resources/data/wild_wind_tests/test_instance/fluid_effects.json @@ -0,0 +1,7 @@ +{ + "type": "minecraft:function", + "function": "wild_wind_tests:fluid_effects", + "environment": "minecraft:default", + "structure": "wild_wind_tests:empty", + "max_ticks": 240 +} diff --git a/src/verification/resources/data/wild_wind_tests/test_instance/fluid_entity_rules.json b/src/verification/resources/data/wild_wind_tests/test_instance/fluid_entity_rules.json new file mode 100644 index 0000000..904f525 --- /dev/null +++ b/src/verification/resources/data/wild_wind_tests/test_instance/fluid_entity_rules.json @@ -0,0 +1,7 @@ +{ + "type": "minecraft:function", + "function": "wild_wind_tests:fluid_entity_rules", + "environment": "minecraft:default", + "structure": "wild_wind_tests:empty", + "max_ticks": 240 +} diff --git a/src/verification/resources/data/wild_wind_tests/test_instance/generation.json b/src/verification/resources/data/wild_wind_tests/test_instance/generation.json new file mode 100644 index 0000000..15d7783 --- /dev/null +++ b/src/verification/resources/data/wild_wind_tests/test_instance/generation.json @@ -0,0 +1,7 @@ +{ + "type": "minecraft:function", + "function": "wild_wind_tests:generation", + "environment": "minecraft:default", + "structure": "ww_structures:smoke", + "max_ticks": 200 +} diff --git a/src/verification/resources/data/wild_wind_tests/test_instance/inspection_blocks.json b/src/verification/resources/data/wild_wind_tests/test_instance/inspection_blocks.json new file mode 100644 index 0000000..03f98a3 --- /dev/null +++ b/src/verification/resources/data/wild_wind_tests/test_instance/inspection_blocks.json @@ -0,0 +1,7 @@ +{ + "type": "minecraft:function", + "function": "wild_wind_tests:inspection_blocks", + "environment": "minecraft:default", + "structure": "wild_wind_tests:empty", + "max_ticks": 100 +} diff --git a/src/verification/resources/data/wild_wind_tests/test_instance/inspection_interactions.json b/src/verification/resources/data/wild_wind_tests/test_instance/inspection_interactions.json new file mode 100644 index 0000000..6cd8d78 --- /dev/null +++ b/src/verification/resources/data/wild_wind_tests/test_instance/inspection_interactions.json @@ -0,0 +1,7 @@ +{ + "type": "minecraft:function", + "function": "wild_wind_tests:inspection_interactions", + "environment": "minecraft:default", + "structure": "wild_wind_tests:empty", + "max_ticks": 100 +} diff --git a/src/verification/resources/data/wild_wind_tests/test_instance/inspection_sulfur.json b/src/verification/resources/data/wild_wind_tests/test_instance/inspection_sulfur.json new file mode 100644 index 0000000..7ddc9fe --- /dev/null +++ b/src/verification/resources/data/wild_wind_tests/test_instance/inspection_sulfur.json @@ -0,0 +1,7 @@ +{ + "type": "minecraft:function", + "function": "wild_wind_tests:inspection_sulfur", + "environment": "minecraft:default", + "structure": "wild_wind_tests:empty", + "max_ticks": 100 +} diff --git a/src/verification/resources/data/wild_wind_tests/test_instance/kiln.json b/src/verification/resources/data/wild_wind_tests/test_instance/kiln.json new file mode 100644 index 0000000..0858c93 --- /dev/null +++ b/src/verification/resources/data/wild_wind_tests/test_instance/kiln.json @@ -0,0 +1,7 @@ +{ + "type": "minecraft:function", + "function": "wild_wind_tests:kiln", + "environment": "minecraft:default", + "structure": "wild_wind_tests:empty", + "max_ticks": 240 +} diff --git a/src/verification/resources/data/wild_wind_tests/test_instance/kiln_inventory.json b/src/verification/resources/data/wild_wind_tests/test_instance/kiln_inventory.json new file mode 100644 index 0000000..54a61d7 --- /dev/null +++ b/src/verification/resources/data/wild_wind_tests/test_instance/kiln_inventory.json @@ -0,0 +1,7 @@ +{ + "type": "minecraft:function", + "function": "wild_wind_tests:kiln_inventory", + "environment": "minecraft:default", + "structure": "wild_wind_tests:empty", + "max_ticks": 240 +} diff --git a/src/verification/resources/data/wild_wind_tests/test_instance/kiln_villages.json b/src/verification/resources/data/wild_wind_tests/test_instance/kiln_villages.json new file mode 100644 index 0000000..846dc6e --- /dev/null +++ b/src/verification/resources/data/wild_wind_tests/test_instance/kiln_villages.json @@ -0,0 +1,7 @@ +{ + "type": "minecraft:function", + "function": "wild_wind_tests:kiln_villages", + "environment": "minecraft:default", + "structure": "wild_wind_tests:empty", + "max_ticks": 240 +} diff --git a/src/verification/resources/data/wild_wind_tests/test_instance/land_choke.json b/src/verification/resources/data/wild_wind_tests/test_instance/land_choke.json new file mode 100644 index 0000000..6b24aef --- /dev/null +++ b/src/verification/resources/data/wild_wind_tests/test_instance/land_choke.json @@ -0,0 +1,7 @@ +{ + "type": "minecraft:function", + "function": "wild_wind_tests:land_choke", + "environment": "minecraft:default", + "structure": "wild_wind_tests:empty", + "max_ticks": 240 +} diff --git a/src/verification/resources/data/wild_wind_tests/test_instance/melting.json b/src/verification/resources/data/wild_wind_tests/test_instance/melting.json new file mode 100644 index 0000000..e5823ca --- /dev/null +++ b/src/verification/resources/data/wild_wind_tests/test_instance/melting.json @@ -0,0 +1,7 @@ +{ + "type": "minecraft:function", + "function": "wild_wind_tests:melting", + "environment": "minecraft:default", + "structure": "wild_wind_tests:empty", + "max_ticks": 240 +} diff --git a/src/verification/resources/data/wild_wind_tests/test_instance/melting_table.json b/src/verification/resources/data/wild_wind_tests/test_instance/melting_table.json new file mode 100644 index 0000000..6cd028a --- /dev/null +++ b/src/verification/resources/data/wild_wind_tests/test_instance/melting_table.json @@ -0,0 +1,7 @@ +{ + "type": "minecraft:function", + "function": "wild_wind_tests:melting_table", + "environment": "minecraft:default", + "structure": "wild_wind_tests:empty", + "max_ticks": 100 +} diff --git a/src/verification/resources/data/wild_wind_tests/test_instance/reach_arrow_acquisition.json b/src/verification/resources/data/wild_wind_tests/test_instance/reach_arrow_acquisition.json new file mode 100644 index 0000000..db79f5a --- /dev/null +++ b/src/verification/resources/data/wild_wind_tests/test_instance/reach_arrow_acquisition.json @@ -0,0 +1,7 @@ +{ + "type": "minecraft:function", + "function": "wild_wind_tests:reach_arrow_acquisition", + "environment": "minecraft:default", + "structure": "wild_wind_tests:empty", + "max_ticks": 240 +} diff --git a/src/verification/resources/data/wild_wind_tests/test_instance/reach_arrows.json b/src/verification/resources/data/wild_wind_tests/test_instance/reach_arrows.json new file mode 100644 index 0000000..15e6fd0 --- /dev/null +++ b/src/verification/resources/data/wild_wind_tests/test_instance/reach_arrows.json @@ -0,0 +1,7 @@ +{ + "type": "minecraft:function", + "function": "wild_wind_tests:reach_arrows", + "environment": "minecraft:default", + "structure": "wild_wind_tests:empty", + "max_ticks": 240 +} diff --git a/src/verification/resources/data/wild_wind_tests/test_instance/skeleton_melee.json b/src/verification/resources/data/wild_wind_tests/test_instance/skeleton_melee.json new file mode 100644 index 0000000..6f507d9 --- /dev/null +++ b/src/verification/resources/data/wild_wind_tests/test_instance/skeleton_melee.json @@ -0,0 +1,7 @@ +{ + "type": "minecraft:function", + "function": "wild_wind_tests:skeleton_melee", + "environment": "minecraft:default", + "structure": "wild_wind_tests:empty", + "max_ticks": 240 +} diff --git a/src/verification/resources/data/wild_wind_tests/test_instance/skeleton_spawns.json b/src/verification/resources/data/wild_wind_tests/test_instance/skeleton_spawns.json new file mode 100644 index 0000000..2286ef2 --- /dev/null +++ b/src/verification/resources/data/wild_wind_tests/test_instance/skeleton_spawns.json @@ -0,0 +1,7 @@ +{ + "type": "minecraft:function", + "function": "wild_wind_tests:skeleton_spawns", + "environment": "minecraft:default", + "structure": "wild_wind_tests:empty", + "max_ticks": 240 +} diff --git a/src/verification/resources/data/wild_wind_tests/test_instance/spawning.json b/src/verification/resources/data/wild_wind_tests/test_instance/spawning.json new file mode 100644 index 0000000..c432495 --- /dev/null +++ b/src/verification/resources/data/wild_wind_tests/test_instance/spawning.json @@ -0,0 +1,7 @@ +{ + "type": "minecraft:function", + "function": "wild_wind_tests:spawning", + "environment": "minecraft:default", + "structure": "wild_wind_tests:empty", + "max_ticks": 100 +} diff --git a/src/verification/resources/data/wild_wind_tests/test_instance/upstream_integration.json b/src/verification/resources/data/wild_wind_tests/test_instance/upstream_integration.json new file mode 100644 index 0000000..65247be --- /dev/null +++ b/src/verification/resources/data/wild_wind_tests/test_instance/upstream_integration.json @@ -0,0 +1,7 @@ +{ + "type": "minecraft:function", + "function": "wild_wind_tests:upstream_integration", + "environment": "minecraft:default", + "structure": "wild_wind_tests:empty", + "max_ticks": 240 +} diff --git a/src/verification/resources/data/wild_wind_tests/test_instance/wool_recipe.json b/src/verification/resources/data/wild_wind_tests/test_instance/wool_recipe.json new file mode 100644 index 0000000..1e76051 --- /dev/null +++ b/src/verification/resources/data/wild_wind_tests/test_instance/wool_recipe.json @@ -0,0 +1,7 @@ +{ + "type": "minecraft:function", + "function": "wild_wind_tests:wool_recipe", + "environment": "minecraft:default", + "structure": "wild_wind_tests:empty", + "max_ticks": 240 +} diff --git a/src/verification/resources/wild_wind_tests.mixins.json b/src/verification/resources/wild_wind_tests.mixins.json new file mode 100644 index 0000000..cb18fe7 --- /dev/null +++ b/src/verification/resources/wild_wind_tests.mixins.json @@ -0,0 +1,7 @@ +{ + "required": true, + "package": "org.polaris2023.wildwind.structures.test.mixin", + "compatibilityLevel": "JAVA_25", + "mixins": ["GameTestServerMixin"], + "injectors": {"defaultRequire": 1} +} diff --git a/src/wilderness/java/org/polaris2023/wildwind/wilderness/WildernessMod.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/WildernessMod.java new file mode 100644 index 0000000..ebf3918 --- /dev/null +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/WildernessMod.java @@ -0,0 +1,29 @@ +package org.polaris2023.wildwind.wilderness; +import net.minecraft.resources.Identifier; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.fml.common.Mod; +import org.polaris2023.wildwind.wilderness.block.ModBlocks; +import org.polaris2023.wildwind.wilderness.registry.*; + +@Mod(WildernessMod.MOD_ID) +public final class WildernessMod { + public static final String MOD_ID = "wild_wind_wilderness"; + public WildernessMod(IEventBus bus) { + ModBlocks.register(bus); + ModEntities.register(bus); + ModItems.register(bus); + org.polaris2023.wildwind.wilderness.effect.ModEffects.register(bus); + ModDataComponents.register(bus); + ModAttributes.register(bus); + ModMobEffects.register(bus); + ModPotions.register(bus); + ModSoundEvents.register(bus); + ModEntityDataSerializers.register(bus); + bus.addListener((net.neoforged.neoforge.registries.DataPackRegistryEvent.NewRegistry event) -> + event.dataPackRegistry(DatadrivenRegistryKey.MUDCRAB_VARIANT, + org.polaris2023.wildwind.wilderness.entity.animal.MudcrabVariant.DIRECT_CODEC, + org.polaris2023.wildwind.wilderness.entity.animal.MudcrabVariant.NETWORK_CODEC)); + + } + public static Identifier id(String path) { return Identifier.fromNamespaceAndPath(MOD_ID, path); } +} diff --git a/src/wilderness/java/org/polaris2023/wildwind/wilderness/arrow/ReachArrows.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/arrow/ReachArrows.java new file mode 100644 index 0000000..d12b24f --- /dev/null +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/arrow/ReachArrows.java @@ -0,0 +1,19 @@ +package org.polaris2023.wildwind.wilderness.arrow; + +import net.minecraft.core.component.DataComponents; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import org.polaris2023.wildwind.wilderness.registry.ModPotions; + +public final class ReachArrows { + private ReachArrows() {} + + /** Preserve counts and potion/custom components when vanilla crafting or trades create Reach arrows. */ + public static ItemStack convert(ItemStack stack) { + var potion = stack.get(DataComponents.POTION_CONTENTS); + if (!stack.is(Items.TIPPED_ARROW) || potion == null || potion.potion().isEmpty()) return stack; + var holder = potion.potion().get(); + if (!holder.is(ModPotions.REACH.getKey()) && !holder.is(ModPotions.LONG_REACH.getKey())) return stack; + return stack.transmuteCopy(org.polaris2023.wildwind.wilderness.registry.ModItems.TIPPED_ARROW.get()); + } +} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/block/ModBlocks.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/block/ModBlocks.java similarity index 62% rename from src/hfas/java/org/polaris2023/wildwind/hfas/block/ModBlocks.java rename to src/wilderness/java/org/polaris2023/wildwind/wilderness/block/ModBlocks.java index 03ee298..729d416 100644 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/block/ModBlocks.java +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/block/ModBlocks.java @@ -1,4 +1,4 @@ -package org.polaris2023.wildwind.hfas.block; +package org.polaris2023.wildwind.wilderness.block; import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.Item; @@ -12,8 +12,8 @@ import net.neoforged.neoforge.registries.DeferredBlock; import net.neoforged.neoforge.registries.DeferredItem; import net.neoforged.neoforge.registries.DeferredRegister; -import org.polaris2023.wildwind.hfas.HFASMod; -import org.polaris2023.wildwind.hfas.worldgen.ModTreeGrowers; +import org.polaris2023.wildwind.wilderness.WildernessMod; +import org.polaris2023.wildwind.wilderness.worldgen.ModTreeGrowers; import java.util.ArrayList; import java.util.List; @@ -29,31 +29,16 @@ */ //TODO 考虑迁移至registry目录下,或将registry目录下的注册条目分散到各目录下 public class ModBlocks { - // 方块注册器 - public static final DeferredRegister.Blocks BLOCKS = DeferredRegister.createBlocks(HFASMod.MOD_ID); - // 物品注册器 - public static final DeferredRegister.Items ITEMS = DeferredRegister.createItems(HFASMod.MOD_ID); - - // ==================== 方块类型定义 ==================== - - // 焚烬木方块类型 + public static final DeferredRegister.Blocks BLOCKS = DeferredRegister.createBlocks(WildernessMod.MOD_ID); + public static final DeferredRegister.Items ITEMS = DeferredRegister.createItems(WildernessMod.MOD_ID); public static final BlockSetType BLAZE_BLOCK_SET = BlockSetType.register(new BlockSetType("blaze")); - // 焚烬木木材类型 + public static final WoodType BLAZE_WOOD_TYPE = WoodType.register(new WoodType("blaze", BLAZE_BLOCK_SET)); - // 灵焰木方块类型 public static final BlockSetType SOUL_BLOCK_SET = BlockSetType.register(new BlockSetType("soul")); - // 灵焰木木材类型 - public static final WoodType SOUL_WOOD_TYPE = WoodType.register(new WoodType("soul", SOUL_BLOCK_SET)); - - // 杜鹃木方块类型 - public static final BlockSetType AZALEA_BLOCK_SET = BlockSetType.register(new BlockSetType("azalea")); - // 杜鹃木木材类型 - public static final WoodType AZALEA_WOOD_TYPE = WoodType.register(new WoodType("azalea", AZALEA_BLOCK_SET)); - // ==================== 焚烬木套件 (blaze_wood) ==================== + public static final WoodType SOUL_WOOD_TYPE = WoodType.register(new WoodType("soul", SOUL_BLOCK_SET)); - // 焚烬木原木 public static final DeferredBlock BLAZE_LOG = BLOCKS.registerBlock( "blaze_log", p -> new RotatedPillarBlock(p @@ -62,7 +47,6 @@ public class ModBlocks { .sound(SoundType.WOOD)) ); - // 焚烬木 public static final DeferredBlock BLAZE_WOOD = BLOCKS.registerBlock( "blaze_wood", p -> new RotatedPillarBlock(p @@ -71,7 +55,6 @@ public class ModBlocks { .sound(SoundType.WOOD)) ); - // 去皮焚烬木原木 public static final DeferredBlock STRIPPED_BLAZE_LOG = BLOCKS.registerBlock( "stripped_blaze_log", p -> new RotatedPillarBlock(p @@ -80,7 +63,6 @@ public class ModBlocks { .sound(SoundType.WOOD)) ); - // 去皮焚烬木 public static final DeferredBlock STRIPPED_BLAZE_WOOD = BLOCKS.registerBlock( "stripped_blaze_wood", p -> new RotatedPillarBlock(p @@ -89,7 +71,6 @@ public class ModBlocks { .sound(SoundType.WOOD)) ); - // 焚烬木木板 public static final DeferredBlock BLAZE_PLANKS = BLOCKS.registerBlock( "blaze_planks", p -> new Block(p @@ -98,7 +79,6 @@ public class ModBlocks { .sound(SoundType.WOOD)) ); - // 焚烬木楼梯 public static final DeferredBlock BLAZE_STAIRS = BLOCKS.registerBlock( "blaze_stairs", p -> new StairBlock(BLAZE_PLANKS.get().defaultBlockState(), p @@ -107,7 +87,6 @@ public class ModBlocks { .sound(SoundType.WOOD)) ); - // 焚烬木台阶 public static final DeferredBlock BLAZE_SLAB = BLOCKS.registerBlock( "blaze_slab", p -> new SlabBlock(p @@ -116,7 +95,6 @@ public class ModBlocks { .sound(SoundType.WOOD)) ); - // 焚烬木栅栏 public static final DeferredBlock BLAZE_FENCE = BLOCKS.registerBlock( "blaze_fence", p -> new FenceBlock(p @@ -125,7 +103,6 @@ public class ModBlocks { .sound(SoundType.WOOD)) ); - // 焚烬木栅栏门 public static final DeferredBlock BLAZE_FENCE_GATE = BLOCKS.registerBlock( "blaze_fence_gate", p -> new FenceGateBlock(BLAZE_WOOD_TYPE, p @@ -134,7 +111,6 @@ public class ModBlocks { .sound(SoundType.WOOD)) ); - // 焚烬木门 public static final DeferredBlock BLAZE_DOOR = BLOCKS.registerBlock( "blaze_door", p -> new DoorBlock(BLAZE_BLOCK_SET, p @@ -143,7 +119,6 @@ public class ModBlocks { .sound(SoundType.WOOD)) ); - // 焚烬木活板门 public static final DeferredBlock BLAZE_TRAPDOOR = BLOCKS.registerBlock( "blaze_trapdoor", p -> new TrapDoorBlock(BLAZE_BLOCK_SET, p @@ -152,7 +127,6 @@ public class ModBlocks { .sound(SoundType.WOOD)) ); - // 焚烬木压力板 public static final DeferredBlock BLAZE_PRESSURE_PLATE = BLOCKS.registerBlock( "blaze_pressure_plate", p -> new PressurePlateBlock(BLAZE_BLOCK_SET, p @@ -161,7 +135,6 @@ public class ModBlocks { .sound(SoundType.WOOD)) ); - // 焚烬木按钮 public static final DeferredBlock BLAZE_BUTTON = BLOCKS.registerBlock( "blaze_button", p -> new ButtonBlock(BLAZE_BLOCK_SET, 30, p @@ -170,10 +143,10 @@ public class ModBlocks { .sound(SoundType.WOOD)) ); - // 焚烬木树叶 public static final DeferredBlock BLAZE_LEAVES = BLOCKS.registerBlock( "blaze_leaves", - p -> new TintedParticleLeavesBlock(0.01F,p + p -> new UntintedParticleLeavesBlock(0.01F, + net.minecraft.core.particles.ColorParticleOption.create(net.minecraft.core.particles.ParticleTypes.TINTED_LEAVES, 0xFFFF8000), p .mapColor(MapColor.COLOR_ORANGE) .strength(0.2F) .sound(SoundType.GRASS) @@ -181,7 +154,6 @@ public class ModBlocks { .randomTicks()) ); - // 焚烬木树苗 public static final DeferredBlock BLAZE_SAPLING = BLOCKS.registerBlock( "blaze_sapling", p -> new SaplingBlock(ModTreeGrowers.BLAZE, p @@ -192,9 +164,6 @@ public class ModBlocks { .randomTicks()) ); - // ==================== 灵焰木套件 (soul_wood) ==================== - - // 灵焰木原木 public static final DeferredBlock SOUL_LOG = BLOCKS.registerBlock( "soul_log", p -> new RotatedPillarBlock(p @@ -203,7 +172,6 @@ public class ModBlocks { .sound(SoundType.WOOD)) ); - // 灵焰木 public static final DeferredBlock SOUL_WOOD = BLOCKS.registerBlock( "soul_wood", p -> new RotatedPillarBlock(p @@ -212,7 +180,6 @@ public class ModBlocks { .sound(SoundType.WOOD)) ); - // 去皮灵焰木原木 public static final DeferredBlock STRIPPED_SOUL_LOG = BLOCKS.registerBlock( "stripped_soul_log", p -> new RotatedPillarBlock(p @@ -221,7 +188,6 @@ public class ModBlocks { .sound(SoundType.WOOD)) ); - // 去皮灵焰木 public static final DeferredBlock STRIPPED_SOUL_WOOD = BLOCKS.registerBlock( "stripped_soul_wood", p -> new RotatedPillarBlock(p @@ -230,7 +196,6 @@ public class ModBlocks { .sound(SoundType.WOOD)) ); - // 灵焰木木板 public static final DeferredBlock SOUL_PLANKS = BLOCKS.registerBlock( "soul_planks", p -> new Block(p @@ -239,7 +204,6 @@ public class ModBlocks { .sound(SoundType.WOOD)) ); - // 灵焰木楼梯 public static final DeferredBlock SOUL_STAIRS = BLOCKS.registerBlock( "soul_stairs", p -> new StairBlock(SOUL_PLANKS.get().defaultBlockState(), p @@ -248,7 +212,6 @@ public class ModBlocks { .sound(SoundType.WOOD)) ); - // 灵焰木台阶 public static final DeferredBlock SOUL_SLAB = BLOCKS.registerBlock( "soul_slab", p -> new SlabBlock(p @@ -257,7 +220,6 @@ public class ModBlocks { .sound(SoundType.WOOD)) ); - // 灵焰木栅栏 public static final DeferredBlock SOUL_FENCE = BLOCKS.registerBlock( "soul_fence", p -> new FenceBlock(p @@ -266,7 +228,6 @@ public class ModBlocks { .sound(SoundType.WOOD)) ); - // 灵焰木栅栏门 public static final DeferredBlock SOUL_FENCE_GATE = BLOCKS.registerBlock( "soul_fence_gate", p -> new FenceGateBlock(SOUL_WOOD_TYPE, p @@ -275,7 +236,6 @@ public class ModBlocks { .sound(SoundType.WOOD)) ); - // 灵焰木门 public static final DeferredBlock SOUL_DOOR = BLOCKS.registerBlock( "soul_door", p -> new DoorBlock(SOUL_BLOCK_SET, p @@ -284,7 +244,6 @@ public class ModBlocks { .sound(SoundType.WOOD)) ); - // 灵焰木活板门 public static final DeferredBlock SOUL_TRAPDOOR = BLOCKS.registerBlock( "soul_trapdoor", p -> new TrapDoorBlock(SOUL_BLOCK_SET, p @@ -293,7 +252,6 @@ public class ModBlocks { .sound(SoundType.WOOD)) ); - // 灵焰木压力板 public static final DeferredBlock SOUL_PRESSURE_PLATE = BLOCKS.registerBlock( "soul_pressure_plate", p -> new PressurePlateBlock(SOUL_BLOCK_SET, p @@ -302,7 +260,6 @@ public class ModBlocks { .sound(SoundType.WOOD)) ); - // 灵焰木按钮 public static final DeferredBlock SOUL_BUTTON = BLOCKS.registerBlock( "soul_button", p -> new ButtonBlock(SOUL_BLOCK_SET, 30, p @@ -311,10 +268,10 @@ public class ModBlocks { .sound(SoundType.WOOD)) ); - // 灵焰木树叶 public static final DeferredBlock SOUL_LEAVES = BLOCKS.registerBlock( "soul_leaves", - p -> new TintedParticleLeavesBlock(0.01F, p + p -> new UntintedParticleLeavesBlock(0.01F, + net.minecraft.core.particles.ColorParticleOption.create(net.minecraft.core.particles.ParticleTypes.TINTED_LEAVES, 0xFF00FFFF), p .mapColor(MapColor.COLOR_CYAN) .strength(0.2F) .sound(SoundType.GRASS) @@ -322,7 +279,6 @@ public class ModBlocks { .randomTicks()) ); - // 灵焰木树苗 public static final DeferredBlock SOUL_SAPLING = BLOCKS.registerBlock( "soul_sapling", p -> new SaplingBlock(ModTreeGrowers.SOUL, p @@ -333,128 +289,6 @@ public class ModBlocks { .randomTicks()) ); - // ==================== 杜鹃木套件 (azalea_wood) ==================== - - // 杜鹃木原木 - public static final DeferredBlock AZALEA_LOG = BLOCKS.registerBlock( - "azalea_log", - p -> new RotatedPillarBlock(p - .mapColor(MapColor.COLOR_LIGHT_GREEN) - .strength(2.0F) - .sound(SoundType.WOOD)) - ); - - // 杜鹃木 - public static final DeferredBlock AZALEA_WOOD = BLOCKS.registerBlock( - "azalea_wood", - p -> new RotatedPillarBlock(p - .mapColor(MapColor.COLOR_LIGHT_GREEN) - .strength(2.0F) - .sound(SoundType.WOOD)) - ); - - // 去皮杜鹃木原木 - public static final DeferredBlock STRIPPED_AZALEA_LOG = BLOCKS.registerBlock( - "stripped_azalea_log", - p -> new RotatedPillarBlock(p - .mapColor(MapColor.COLOR_LIGHT_GREEN) - .strength(2.0F) - .sound(SoundType.WOOD)) - ); - - // 去皮杜鹃木 - public static final DeferredBlock STRIPPED_AZALEA_WOOD = BLOCKS.registerBlock( - "stripped_azalea_wood", - p -> new RotatedPillarBlock(p - .mapColor(MapColor.COLOR_LIGHT_GREEN) - .strength(2.0F) - .sound(SoundType.WOOD)) - ); - - // 杜鹃木木板 - public static final DeferredBlock AZALEA_PLANKS = BLOCKS.registerBlock( - "azalea_planks", - p -> new Block(p - .mapColor(MapColor.COLOR_LIGHT_GREEN) - .strength(2.0F) - .sound(SoundType.WOOD)) - ); - - // 杜鹃木楼梯 - public static final DeferredBlock AZALEA_STAIRS = BLOCKS.registerBlock( - "azalea_stairs", - p -> new StairBlock(AZALEA_PLANKS.get().defaultBlockState(), p - .mapColor(MapColor.COLOR_LIGHT_GREEN) - .strength(2.0F) - .sound(SoundType.WOOD)) - ); - - // 杜鹃木台阶 - public static final DeferredBlock AZALEA_SLAB = BLOCKS.registerBlock( - "azalea_slab", - p -> new SlabBlock(p - .mapColor(MapColor.COLOR_LIGHT_GREEN) - .strength(2.0F) - .sound(SoundType.WOOD)) - ); - - // 杜鹃木栅栏 - public static final DeferredBlock AZALEA_FENCE = BLOCKS.registerBlock( - "azalea_fence", - p -> new FenceBlock(p - .mapColor(MapColor.COLOR_LIGHT_GREEN) - .strength(2.0F) - .sound(SoundType.WOOD)) - ); - - // 杜鹃木栅栏门 - public static final DeferredBlock AZALEA_FENCE_GATE = BLOCKS.registerBlock( - "azalea_fence_gate", - p -> new FenceGateBlock(AZALEA_WOOD_TYPE, p - .mapColor(MapColor.COLOR_LIGHT_GREEN) - .strength(2.0F) - .sound(SoundType.WOOD)) - ); - - // 杜鹃木门 - public static final DeferredBlock AZALEA_DOOR = BLOCKS.registerBlock( - "azalea_door", - p -> new DoorBlock(AZALEA_BLOCK_SET, p - .mapColor(MapColor.COLOR_LIGHT_GREEN) - .strength(2.0F) - .sound(SoundType.WOOD)) - ); - - // 杜鹃木活板门 - public static final DeferredBlock AZALEA_TRAPDOOR = BLOCKS.registerBlock( - "azalea_trapdoor", - p -> new TrapDoorBlock(AZALEA_BLOCK_SET, p - .mapColor(MapColor.COLOR_LIGHT_GREEN) - .strength(2.0F) - .sound(SoundType.WOOD)) - ); - - // 杜鹃木压力板 - public static final DeferredBlock AZALEA_PRESSURE_PLATE = BLOCKS.registerBlock( - "azalea_pressure_plate", - p -> new PressurePlateBlock(AZALEA_BLOCK_SET, p - .mapColor(MapColor.COLOR_LIGHT_GREEN) - .strength(0.5F) - .sound(SoundType.WOOD)) - ); - - // 杜鹃木按钮 - public static final DeferredBlock AZALEA_BUTTON = BLOCKS.registerBlock( - "azalea_button", - p -> new ButtonBlock(AZALEA_BLOCK_SET, 30, p - .mapColor(MapColor.COLOR_LIGHT_GREEN) - .strength(0.5F) - .sound(SoundType.WOOD)) - ); - - // ==================== 其他方块 ==================== - - // 焦灰草方块 (scorched_grass_block) public static final DeferredBlock SCORCHED_GRASS_BLOCK = BLOCKS.registerBlock( "scorched_grass_block", p -> new Block(p @@ -464,7 +298,6 @@ public class ModBlocks { .randomTicks()) ); - // 焦土 (scorched_dirt) public static final DeferredBlock SCORCHED_DIRT = BLOCKS.registerBlock( "scorched_dirt", p -> new Block(p @@ -473,7 +306,6 @@ public class ModBlocks { .sound(SoundType.GRAVEL)) ); - // 焦灰草丛 (scorched_grass) public static final DeferredBlock SCORCHED_GRASS = BLOCKS.registerBlock( "scorched_grass", p -> new Block(p @@ -484,7 +316,6 @@ public class ModBlocks { .pushReaction(PushReaction.DESTROY)) ); - // 焦灰枝条 (scorched_twig) public static final DeferredBlock SCORCHED_TWIG = BLOCKS.registerBlock( "scorched_twig", p -> new Block(p @@ -495,28 +326,7 @@ public class ModBlocks { .pushReaction(PushReaction.DESTROY)) ); - // 仙人球 (tiny_cactus) - public static final DeferredBlock TINY_CACTUS = BLOCKS.registerBlock( - "tiny_cactus", - p -> new Block(p - .mapColor(MapColor.PLANT) - .noCollision() - .instabreak() - .sound(SoundType.WOOL) - .pushReaction(PushReaction.DESTROY)) - ); - - // 制箭台 (fletching_table) - 使用自定义方块类支持GUI - public static final DeferredBlock FLETCHING_TABLE = BLOCKS.registerBlock( - "fletching_table", - p -> new FletchingTableBlock(p - .mapColor(MapColor.WOOD) - .strength(2.5F) - .sound(SoundType.WOOD)) - ); - - public static void blockItems() { - // 焚烬木套件物品 + private static void blockItems() { ITEMS.registerSimpleBlockItem(BLAZE_LOG); ITEMS.registerSimpleBlockItem(BLAZE_WOOD); ITEMS.registerSimpleBlockItem(STRIPPED_BLAZE_LOG); @@ -532,8 +342,6 @@ public static void blockItems() { ITEMS.registerSimpleBlockItem(BLAZE_BUTTON); ITEMS.registerSimpleBlockItem(BLAZE_LEAVES); ITEMS.registerSimpleBlockItem(BLAZE_SAPLING); - - // 灵焰木套件物品 ITEMS.registerSimpleBlockItem(SOUL_LOG); ITEMS.registerSimpleBlockItem(SOUL_WOOD); ITEMS.registerSimpleBlockItem(STRIPPED_SOUL_LOG); @@ -549,37 +357,10 @@ public static void blockItems() { ITEMS.registerSimpleBlockItem(SOUL_BUTTON); ITEMS.registerSimpleBlockItem(SOUL_LEAVES); ITEMS.registerSimpleBlockItem(SOUL_SAPLING); - - // 杜鹃木套件物品 - ITEMS.registerSimpleBlockItem(AZALEA_LOG); - ITEMS.registerSimpleBlockItem(AZALEA_WOOD); - ITEMS.registerSimpleBlockItem(STRIPPED_AZALEA_LOG); - ITEMS.registerSimpleBlockItem(STRIPPED_AZALEA_WOOD); - ITEMS.registerSimpleBlockItem(AZALEA_PLANKS); - ITEMS.registerSimpleBlockItem(AZALEA_STAIRS); - ITEMS.registerSimpleBlockItem(AZALEA_SLAB); - ITEMS.registerSimpleBlockItem(AZALEA_FENCE); - ITEMS.registerSimpleBlockItem(AZALEA_FENCE_GATE); - ITEMS.registerSimpleBlockItem(AZALEA_DOOR); - ITEMS.registerSimpleBlockItem(AZALEA_TRAPDOOR); - ITEMS.registerSimpleBlockItem(AZALEA_PRESSURE_PLATE); - ITEMS.registerSimpleBlockItem(AZALEA_BUTTON); - - // 其他方块物品 ITEMS.registerSimpleBlockItem(SCORCHED_GRASS_BLOCK); ITEMS.registerSimpleBlockItem(SCORCHED_DIRT); ITEMS.registerSimpleBlockItem(SCORCHED_GRASS); ITEMS.registerSimpleBlockItem(SCORCHED_TWIG); - ITEMS.registerSimpleBlockItem(TINY_CACTUS); - } - - /** - * 注册方块和物品到事件总线 - * 必须在模组构造函数中调用 - */ - public static void register(IEventBus bus) { - BLOCKS.register(bus); - blockItems(); - ITEMS.register(bus); } + public static void register(IEventBus bus) { BLOCKS.register(bus); blockItems(); ITEMS.register(bus); } } diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/client/ModClientHooks.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/client/ModClientHooks.java similarity index 82% rename from src/hfas/java/org/polaris2023/wildwind/hfas/client/ModClientHooks.java rename to src/wilderness/java/org/polaris2023/wildwind/wilderness/client/ModClientHooks.java index fad223f..5c0dec1 100644 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/client/ModClientHooks.java +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/client/ModClientHooks.java @@ -1,4 +1,4 @@ -package org.polaris2023.wildwind.hfas.client; +package org.polaris2023.wildwind.wilderness.client; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.world.inventory.Slot; @@ -9,11 +9,11 @@ import net.neoforged.neoforge.client.event.RegisterClientTooltipComponentFactoriesEvent; import net.neoforged.neoforge.client.event.ScreenEvent; import net.neoforged.neoforge.client.network.ClientPacketDistributor; -import org.polaris2023.wildwind.hfas.HFASMod; -import org.polaris2023.wildwind.hfas.client.tooltip.ClientOmniClawTooltip; -import org.polaris2023.wildwind.hfas.component.OmniClawTools; -import org.polaris2023.wildwind.hfas.network.payload.ServerBoundSelectOmniClawItemPayload; -import org.polaris2023.wildwind.hfas.registry.ModDataComponents; +import org.polaris2023.wildwind.wilderness.WildernessMod; +import org.polaris2023.wildwind.wilderness.client.tooltip.ClientOmniClawTooltip; +import org.polaris2023.wildwind.wilderness.component.OmniClawTools; +import org.polaris2023.wildwind.wilderness.network.payload.ServerBoundSelectOmniClawItemPayload; +import org.polaris2023.wildwind.wilderness.registry.ModDataComponents; import java.util.List; @@ -23,9 +23,10 @@ * 26.2 迁移说明:PacketDistributor.sendToServer 迁移至 ClientPacketDistributor; * AbstractContainerScreen#getSlotUnderMouse 废弃,改用 getHoveredSlot()。 */ -@EventBusSubscriber(modid = HFASMod.MOD_ID, value = Dist.CLIENT) +@EventBusSubscriber(modid = WildernessMod.MOD_ID, value = Dist.CLIENT) public class ModClientHooks { + /** * 注册全能蟹钳的客户端提示组件工厂喵~ * @@ -75,4 +76,4 @@ static void onScreenPreMouseScroll(ScreenEvent.MouseScrolled.Pre event) { private ModClientHooks() { } -} \ No newline at end of file +} diff --git a/src/wilderness/java/org/polaris2023/wildwind/wilderness/client/ModEntityRenderers.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/client/ModEntityRenderers.java new file mode 100644 index 0000000..af969dd --- /dev/null +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/client/ModEntityRenderers.java @@ -0,0 +1,26 @@ +package org.polaris2023.wildwind.wilderness.client; + +import net.neoforged.api.distmarker.Dist; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.client.event.EntityRenderersEvent; +import org.polaris2023.wildwind.wilderness.WildernessMod; +import org.polaris2023.wildwind.wilderness.registry.ModEntities; + +@EventBusSubscriber(modid = WildernessMod.MOD_ID, value = Dist.CLIENT) +public final class ModEntityRenderers { + private ModEntityRenderers() {} + + @SubscribeEvent + public static void registerRenderers(EntityRenderersEvent.RegisterRenderers event) { + event.registerEntityRenderer(ModEntities.MUDDY_PIG.get(), MuddyPigRenderer::new); + event.registerEntityRenderer(ModEntities.REACH_ARROW.get(), net.minecraft.client.renderer.entity.TippableArrowRenderer::new); + } + + @SubscribeEvent + public static void registerLayers(EntityRenderersEvent.RegisterLayerDefinitions event) { + event.registerLayerDefinition(MuddyPigRenderer.ADULT, MuddyPigModel::adultLayer); + event.registerLayerDefinition(MuddyPigRenderer.BABY, MuddyPigModel::babyLayer); + event.registerLayerDefinition(MuddyPigRenderer.SADDLE, MuddyPigModel::saddleLayer); + } +} diff --git a/src/wilderness/java/org/polaris2023/wildwind/wilderness/client/MuddyPigModel.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/client/MuddyPigModel.java new file mode 100644 index 0000000..8db6c54 --- /dev/null +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/client/MuddyPigModel.java @@ -0,0 +1,71 @@ +package org.polaris2023.wildwind.wilderness.client; + +import net.minecraft.client.model.animal.pig.PigModel; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.client.model.geom.PartPose; +import net.minecraft.client.model.geom.builders.CubeDeformation; +import net.minecraft.client.model.geom.builders.CubeListBuilder; +import net.minecraft.client.model.geom.builders.LayerDefinition; +import net.minecraft.client.model.geom.builders.MeshDefinition; +import net.minecraft.client.model.geom.builders.PartDefinition; + +/** Geometry/UVs from the supplied Blockbench files; animation is inherited from PigModel. */ +public final class MuddyPigModel extends PigModel { + public MuddyPigModel(ModelPart root) { + super(root); + } + + public static LayerDefinition adultLayer() { + return adultLayer(CubeDeformation.NONE, true); + } + + public static LayerDefinition saddleLayer() { + return adultLayer(new CubeDeformation(0.5F), false); + } + + private static LayerDefinition adultLayer(CubeDeformation deformation, boolean flower) { + MeshDefinition mesh = new MeshDefinition(); + PartDefinition root = mesh.getRoot(); + CubeListBuilder head = CubeListBuilder.create() + .texOffs(0, 0).addBox(-4, -4, -8, 8, 8, 8, deformation) + .texOffs(16, 16).addBox(-2, 0, -9, 4, 3, 1, deformation); + if (flower) { + head.texOffs(24, -4).addBox(0, -10, -9, 0, 6, 6) + .texOffs(24, 2).addBox(-3, -10, -6, 6, 6, 0); + } + root.addOrReplaceChild("head", head, PartPose.offset(0, 10, -7)); + // Recenter the authored rotated body without changing its transformed geometry or UVs. + root.addOrReplaceChild("body", CubeListBuilder.create().texOffs(28, 8) + .addBox(-5, -8, -4, 10, 16, 8, deformation), + PartPose.offsetAndRotation(0, 14, 0, (float) (Math.PI / 2), 0, 0)); + leg(root, "right_hind_leg", -3, 18, 6, 4, 6, 0, 16, deformation); + leg(root, "left_hind_leg", 3, 18, 6, 4, 6, 0, 16, deformation); + leg(root, "right_front_leg", -3, 18, -6, 4, 6, 0, 16, deformation); + leg(root, "left_front_leg", 3, 18, -6, 4, 6, 0, 16, deformation); + return LayerDefinition.create(mesh, 64, 64); + } + + public static LayerDefinition babyLayer() { + MeshDefinition mesh = new MeshDefinition(); + PartDefinition root = mesh.getRoot(); + // Blockbench Java coordinates are (-x, 24-y, z). Preserve the baby's authored offset. + root.addOrReplaceChild("body", CubeListBuilder.create().texOffs(0, 0) + .addBox(-3.5F, -3, -4.5F, 7, 6, 9), PartPose.offset(-0.5F, 19, 0.5F)); + root.addOrReplaceChild("head", CubeListBuilder.create() + .texOffs(0, 15).addBox(-3.5F, -5, -5, 7, 6, 6) + .texOffs(6, 27).addBox(-1.5F, -2, -6, 3, 2, 1) + .texOffs(0, 14).addBox(-0.5F, -9, -5, 0, 4, 3) + .texOffs(0, 17).addBox(-2, -9, -3, 3, 4, 0), PartPose.offset(-0.5F, 19, -2)); + leg(root, "left_hind_leg", 2, 22, 4, 2, 2, 0, 0, CubeDeformation.NONE); + leg(root, "right_hind_leg", -3, 22, 4, 2, 2, 23, 0, CubeDeformation.NONE); + leg(root, "left_front_leg", 2, 22, -3, 2, 2, 0, 4, CubeDeformation.NONE); + leg(root, "right_front_leg", -3, 22, -3, 2, 2, 23, 4, CubeDeformation.NONE); + return LayerDefinition.create(mesh, 32, 32); + } + + private static void leg(PartDefinition root, String name, float x, float y, float z, + float width, float height, int u, int v, CubeDeformation deformation) { + root.addOrReplaceChild(name, CubeListBuilder.create().texOffs(u, v) + .addBox(-width / 2, 0, -width / 2, width, height, width, deformation), PartPose.offset(x, y, z)); + } +} diff --git a/src/wilderness/java/org/polaris2023/wildwind/wilderness/client/MuddyPigRenderer.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/client/MuddyPigRenderer.java new file mode 100644 index 0000000..622e0fb --- /dev/null +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/client/MuddyPigRenderer.java @@ -0,0 +1,63 @@ +package org.polaris2023.wildwind.wilderness.client; + +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.model.AdultAndBabyModelPair; +import net.minecraft.client.model.geom.ModelLayerLocation; +import net.minecraft.client.renderer.SubmitNodeCollector; +import net.minecraft.client.renderer.entity.EntityRendererProvider; +import net.minecraft.client.renderer.entity.MobRenderer; +import net.minecraft.client.renderer.entity.layers.SimpleEquipmentLayer; +import net.minecraft.client.renderer.entity.state.PigRenderState; +import net.minecraft.client.renderer.state.level.CameraRenderState; +import net.minecraft.client.resources.model.EquipmentClientInfo; +import net.minecraft.resources.Identifier; +import net.minecraft.world.entity.EquipmentSlot; +import org.polaris2023.wildwind.wilderness.WildernessMod; +import org.polaris2023.wildwind.wilderness.entity.MuddyPig; + +public final class MuddyPigRenderer extends MobRenderer { + public static final ModelLayerLocation ADULT = layer("main"); + public static final ModelLayerLocation BABY = layer("baby"); + public static final ModelLayerLocation SADDLE = layer("saddle"); + private static final Identifier ADULT_TEXTURE = texture("pig_muddy"); + private static final Identifier BABY_TEXTURE = texture("pig_muddy_baby"); + private final AdultAndBabyModelPair models; + + public MuddyPigRenderer(EntityRendererProvider.Context context) { + super(context, new MuddyPigModel(context.bakeLayer(ADULT)), 0.7F); + models = new AdultAndBabyModelPair<>(model, new MuddyPigModel(context.bakeLayer(BABY))); + addLayer(new SimpleEquipmentLayer<>(this, context.getEquipmentRenderer(), + EquipmentClientInfo.LayerType.PIG_SADDLE, state -> state.saddle, + new MuddyPigModel(context.bakeLayer(SADDLE)), null)); + } + + @Override + public void submit(PigRenderState state, PoseStack poseStack, SubmitNodeCollector collector, CameraRenderState camera) { + model = models.getModel(state.isBaby); + super.submit(state, poseStack, collector, camera); + } + + @Override + public Identifier getTextureLocation(PigRenderState state) { + return state.isBaby ? BABY_TEXTURE : ADULT_TEXTURE; + } + + @Override + public PigRenderState createRenderState() { + return new PigRenderState(); + } + + @Override + public void extractRenderState(MuddyPig entity, PigRenderState state, float partialTicks) { + super.extractRenderState(entity, state, partialTicks); + state.saddle = entity.getItemBySlot(EquipmentSlot.SADDLE).copy(); + } + + private static ModelLayerLocation layer(String name) { + return new ModelLayerLocation(Identifier.fromNamespaceAndPath(WildernessMod.MOD_ID, "muddy_pig"), name); + } + + private static Identifier texture(String name) { + return Identifier.fromNamespaceAndPath(WildernessMod.MOD_ID, "textures/entity/pig/" + name + ".png"); + } +} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/client/entity/model/MudcrabModel.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/client/entity/model/MudcrabModel.java similarity index 66% rename from src/hfas/java/org/polaris2023/wildwind/hfas/client/entity/model/MudcrabModel.java rename to src/wilderness/java/org/polaris2023/wildwind/wilderness/client/entity/model/MudcrabModel.java index df0980d..b638dcf 100644 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/client/entity/model/MudcrabModel.java +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/client/entity/model/MudcrabModel.java @@ -1,13 +1,13 @@ -package org.polaris2023.wildwind.hfas.client.entity.model; +package org.polaris2023.wildwind.wilderness.client.entity.model; import com.geckolib.model.DefaultedEntityGeoModel; import com.geckolib.renderer.base.GeoRenderState; import net.minecraft.client.renderer.entity.state.EntityRenderState; import net.minecraft.resources.Identifier; -import org.polaris2023.wildwind.hfas.HFASMod; -import org.polaris2023.wildwind.hfas.client.entity.renderstate.MudcrabRenderState; -import org.polaris2023.wildwind.hfas.entity.animal.Mudcrab; +import org.polaris2023.wildwind.wilderness.WildernessMod; +import org.polaris2023.wildwind.wilderness.client.entity.renderstate.MudcrabRenderState; +import org.polaris2023.wildwind.wilderness.entity.animal.Mudcrab; /** * 泥沼蟹实体的几何模型定义喵~ @@ -18,7 +18,7 @@ public class MudcrabModel extends DefaultedEntityGeoModel { * 创建泥沼蟹模型实例喵~ */ public MudcrabModel() { - super(HFASMod.id("mudcrab")); + super(WildernessMod.id("mudcrab")); } /** diff --git a/src/wilderness/java/org/polaris2023/wildwind/wilderness/client/entity/model/PiranhaModel.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/client/entity/model/PiranhaModel.java new file mode 100644 index 0000000..9e136f0 --- /dev/null +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/client/entity/model/PiranhaModel.java @@ -0,0 +1,28 @@ +package org.polaris2023.wildwind.wilderness.client.entity.model; + +import com.geckolib.model.DefaultedEntityGeoModel; +import com.geckolib.renderer.base.GeoRenderState; +import net.minecraft.resources.Identifier; +import org.polaris2023.wildwind.wilderness.WildernessMod; +import org.polaris2023.wildwind.wilderness.entity.animal.Piranha; + +/** + * 食人鱼实体的几何模型定义喵~ + */ +public class PiranhaModel extends DefaultedEntityGeoModel { + + /** + * 创建食人鱼模型实例喵~ + */ + public PiranhaModel() { + super(WildernessMod.id("piranha")); + } + + /** + * 获取当前食人鱼对应的材质资源喵~ + */ + @Override + public Identifier getTextureResource(GeoRenderState state) { + return WildernessMod.id("textures/entity/piranha.png"); + } +} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/client/entity/renderer/MudcrabRenderer.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/client/entity/renderer/MudcrabRenderer.java similarity index 92% rename from src/hfas/java/org/polaris2023/wildwind/hfas/client/entity/renderer/MudcrabRenderer.java rename to src/wilderness/java/org/polaris2023/wildwind/wilderness/client/entity/renderer/MudcrabRenderer.java index 9a7d594..958d3f5 100644 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/client/entity/renderer/MudcrabRenderer.java +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/client/entity/renderer/MudcrabRenderer.java @@ -1,4 +1,4 @@ -package org.polaris2023.wildwind.hfas.client.entity.renderer; +package org.polaris2023.wildwind.wilderness.client.entity.renderer; import com.geckolib.renderer.GeoEntityRenderer; import com.geckolib.renderer.base.RenderPassInfo; @@ -9,9 +9,9 @@ import net.minecraft.client.renderer.item.ItemModelResolver; import net.minecraft.util.Mth; import net.minecraft.world.entity.LivingEntity; -import org.polaris2023.wildwind.hfas.client.entity.model.MudcrabModel; -import org.polaris2023.wildwind.hfas.client.entity.renderstate.MudcrabRenderState; -import org.polaris2023.wildwind.hfas.entity.animal.Mudcrab; +import org.polaris2023.wildwind.wilderness.client.entity.model.MudcrabModel; +import org.polaris2023.wildwind.wilderness.client.entity.renderstate.MudcrabRenderState; +import org.polaris2023.wildwind.wilderness.entity.animal.Mudcrab; import javax.annotation.Nullable; diff --git a/src/wilderness/java/org/polaris2023/wildwind/wilderness/client/entity/renderer/PiranhaRenderer.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/client/entity/renderer/PiranhaRenderer.java new file mode 100644 index 0000000..5514383 --- /dev/null +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/client/entity/renderer/PiranhaRenderer.java @@ -0,0 +1,24 @@ +package org.polaris2023.wildwind.wilderness.client.entity.renderer; + +import com.geckolib.renderer.GeoEntityRenderer; +import net.minecraft.client.renderer.entity.EntityRendererProvider; +import org.polaris2023.wildwind.wilderness.client.entity.model.PiranhaModel; +import org.polaris2023.wildwind.wilderness.client.entity.renderstate.PiranhaRenderState; +import org.polaris2023.wildwind.wilderness.entity.animal.Piranha; + +import javax.annotation.Nullable; + +/** + * 食人鱼渲染器 + * @author huimanman + */ +public class PiranhaRenderer extends GeoEntityRenderer { + public PiranhaRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new PiranhaModel()); + } + + @Override + public PiranhaRenderState createRenderState(Piranha animatable, @Nullable Void relatedObject) { + return new PiranhaRenderState(); + } +} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/client/entity/renderstate/MudcrabRenderState.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/client/entity/renderstate/MudcrabRenderState.java similarity index 69% rename from src/hfas/java/org/polaris2023/wildwind/hfas/client/entity/renderstate/MudcrabRenderState.java rename to src/wilderness/java/org/polaris2023/wildwind/wilderness/client/entity/renderstate/MudcrabRenderState.java index 33c3cc0..d77b0df 100644 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/client/entity/renderstate/MudcrabRenderState.java +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/client/entity/renderstate/MudcrabRenderState.java @@ -1,12 +1,12 @@ -package org.polaris2023.wildwind.hfas.client.entity.renderstate; +package org.polaris2023.wildwind.wilderness.client.entity.renderstate; import net.minecraft.core.Direction; import net.minecraft.client.renderer.entity.state.LivingEntityRenderState; -import org.polaris2023.wildwind.hfas.entity.animal.MudcrabVariant; +import org.polaris2023.wildwind.wilderness.entity.animal.MudcrabVariant; public class MudcrabRenderState extends LivingEntityRenderState { public MudcrabVariant variant; public float modelYRotOffset; public float modelXRotOffset; public Direction motionDirection = Direction.NORTH; -} \ No newline at end of file +} diff --git a/src/wilderness/java/org/polaris2023/wildwind/wilderness/client/entity/renderstate/PiranhaRenderState.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/client/entity/renderstate/PiranhaRenderState.java new file mode 100644 index 0000000..9f8b829 --- /dev/null +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/client/entity/renderstate/PiranhaRenderState.java @@ -0,0 +1,9 @@ +package org.polaris2023.wildwind.wilderness.client.entity.renderstate; + +import net.minecraft.client.renderer.entity.state.LivingEntityRenderState; + +/** + * 食人鱼渲染状态喵~ + */ +public class PiranhaRenderState extends LivingEntityRenderState { +} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/client/eventsub/EntitiesClientHandler.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/client/eventsub/EntitiesClientHandler.java similarity index 55% rename from src/hfas/java/org/polaris2023/wildwind/hfas/client/eventsub/EntitiesClientHandler.java rename to src/wilderness/java/org/polaris2023/wildwind/wilderness/client/eventsub/EntitiesClientHandler.java index 1ddcc3a..7785460 100644 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/client/eventsub/EntitiesClientHandler.java +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/client/eventsub/EntitiesClientHandler.java @@ -1,16 +1,18 @@ -package org.polaris2023.wildwind.hfas.client.eventsub; +package org.polaris2023.wildwind.wilderness.client.eventsub; import net.neoforged.api.distmarker.Dist; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.neoforge.client.event.EntityRenderersEvent; -import org.polaris2023.wildwind.hfas.client.entity.renderer.MudcrabRenderer; -import org.polaris2023.wildwind.hfas.registry.ModEntities; +import org.polaris2023.wildwind.wilderness.client.entity.renderer.MudcrabRenderer; +import org.polaris2023.wildwind.wilderness.client.entity.renderer.PiranhaRenderer; +import org.polaris2023.wildwind.wilderness.registry.ModEntities; @EventBusSubscriber(value = Dist.CLIENT) public class EntitiesClientHandler { @SubscribeEvent static void registerRenderers(EntityRenderersEvent.RegisterRenderers event) { + event.registerEntityRenderer(ModEntities.PIRANHA.get(), PiranhaRenderer::new); event.registerEntityRenderer(ModEntities.MUDCRAB.get(), MudcrabRenderer::new); } -} \ No newline at end of file +} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/client/tooltip/ClientOmniClawTooltip.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/client/tooltip/ClientOmniClawTooltip.java similarity index 96% rename from src/hfas/java/org/polaris2023/wildwind/hfas/client/tooltip/ClientOmniClawTooltip.java rename to src/wilderness/java/org/polaris2023/wildwind/wilderness/client/tooltip/ClientOmniClawTooltip.java index 2c86888..fc66555 100644 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/client/tooltip/ClientOmniClawTooltip.java +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/client/tooltip/ClientOmniClawTooltip.java @@ -1,4 +1,4 @@ -package org.polaris2023.wildwind.hfas.client.tooltip; +package org.polaris2023.wildwind.wilderness.client.tooltip; import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphicsExtractor; @@ -6,7 +6,7 @@ import net.minecraft.client.renderer.RenderPipelines; import net.minecraft.resources.Identifier; import net.minecraft.world.item.ItemStack; -import org.polaris2023.wildwind.hfas.component.OmniClawTools; +import org.polaris2023.wildwind.wilderness.component.OmniClawTools; /** * 全能蟹钳工具列表的客户端提示组件喵~ @@ -99,4 +99,4 @@ public void extractImage(Font font, int x, int y, int w, int h, GuiGraphicsExtra x += SLOT_WIDTH; } } -} \ No newline at end of file +} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/component/OmniClawTools.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/component/OmniClawTools.java similarity index 99% rename from src/hfas/java/org/polaris2023/wildwind/hfas/component/OmniClawTools.java rename to src/wilderness/java/org/polaris2023/wildwind/wilderness/component/OmniClawTools.java index f54311f..90d4b1b 100644 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/component/OmniClawTools.java +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/component/OmniClawTools.java @@ -1,4 +1,4 @@ -package org.polaris2023.wildwind.hfas.component; +package org.polaris2023.wildwind.wilderness.component; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; @@ -372,4 +372,4 @@ public boolean equals(Object obj) { public int hashCode() { return 31 * ItemStack.hashStackList(this.toolList) + this.selectedTool; } -} \ No newline at end of file +} diff --git a/src/wilderness/java/org/polaris2023/wildwind/wilderness/effect/FluidEffects.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/effect/FluidEffects.java new file mode 100644 index 0000000..967263c --- /dev/null +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/effect/FluidEffects.java @@ -0,0 +1,80 @@ +package org.polaris2023.wildwind.wilderness.effect; + +import net.minecraft.tags.FluidTags; +import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.EntityTypes; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.effect.MobEffectUtil; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.phys.Vec3; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.event.entity.living.LivingBreatheEvent; +import net.neoforged.neoforge.event.tick.EntityTickEvent; +import org.polaris2023.wildwind.wilderness.WildernessMod; +import org.polaris2023.wildwind.wilderness.entity.ModEntityTypeTags; + +@EventBusSubscriber(modid = WildernessMod.MOD_ID) +public final class FluidEffects { + private FluidEffects() {} + + public static boolean cannotRise(Entity entity) { + return entity instanceof LivingEntity living && living.is(ModEntityTypeTags.SINK_AFFECTED) + && living.hasEffect(ModEffects.SINK) + && entity.getFluidInteraction().isInFluidMatching(entity, (e, type, height) -> !type.isAir()); + } + + public static Vec3 restrictMovement(Entity entity, Vec3 movement) { + if (movement.y > 0 && cannotRise(entity)) return new Vec3(movement.x, 0, movement.z); + return movement; + } + + @SubscribeEvent + public static void beforeTick(EntityTickEvent.Pre event) { + var entity = event.getEntity(); + entity.setDeltaMovement(restrictMovement(entity, entity.getDeltaMovement())); + } + + @SubscribeEvent + public static void afterTick(EntityTickEvent.Post event) { + var entity = event.getEntity(); + entity.setDeltaMovement(restrictMovement(entity, entity.getDeltaMovement())); + } + + @SubscribeEvent + public static void breathe(LivingBreatheEvent event) { + var entity = event.getEntity(); + if (!entity.isEyeInFluid(FluidTags.WATER)) return; + if (entity.is(ModEntityTypeTags.WATER_BREATHING)) { + event.setCanBreathe(true); + event.setConsumeAirAmount(0); + // Refill even an already empty air meter (e.g. after /reload) before the drowning check. + event.setRefillAirAmount(Math.max(event.getRefillAirAmount(), + entity.getMaxAirSupply() - entity.getAirSupply())); + return; + } + var effect = entity.getEffect(ModEffects.CHOKE); + if (effect != null && entity.is(ModEntityTypeTags.CHOKE_AFFECTED) + && !MobEffectUtil.hasWaterBreathing(entity) + && !(entity instanceof Player player && player.getAbilities().invulnerable) + && !entity.level().getBlockState(BlockPos.containing(entity.getEyePosition())).is(Blocks.BUBBLE_COLUMN)) { + // The whitelist also includes innate water-breathers (e.g. frogs and turtles). + event.setCanBreathe(false); + // I consumes twice as much air, II three times, etc. Preserve respiration's zero-consumption ticks. + long amount = (long) event.getConsumeAirAmount() * (effect.getAmplifier() + 2L); + event.setConsumeAirAmount((int) Math.min(Integer.MAX_VALUE, amount)); + } + } + + /** Used before vanilla land drying, which otherwise overwrites changes made by the breathing event. */ + public static int airBeforeDrying(LivingEntity entity, int air) { + if ((entity.getType() != EntityTypes.TADPOLE && entity.getType() != EntityTypes.AXOLOTL) + || entity.isInWater()) return air; + var effect = entity.getEffect(ModEffects.CHOKE); + if (effect == null) return air; + // Vanilla subtracts the final one and performs its usual drying damage/reset afterwards. + return (int) Math.max(Integer.MIN_VALUE + 1L, (long) air - effect.getAmplifier() - 1L); + } +} diff --git a/src/wilderness/java/org/polaris2023/wildwind/wilderness/effect/ModEffects.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/effect/ModEffects.java new file mode 100644 index 0000000..8ec14d3 --- /dev/null +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/effect/ModEffects.java @@ -0,0 +1,20 @@ +package org.polaris2023.wildwind.wilderness.effect; + +import net.minecraft.core.registries.Registries; +import net.minecraft.world.effect.MobEffect; +import net.minecraft.world.effect.MobEffectCategory; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.neoforge.registries.DeferredHolder; +import net.neoforged.neoforge.registries.DeferredRegister; +import org.polaris2023.wildwind.wilderness.WildernessMod; + +public final class ModEffects { + private static final DeferredRegister EFFECTS = DeferredRegister.create(Registries.MOB_EFFECT, WildernessMod.MOD_ID); + public static final DeferredHolder SINK = EFFECTS.register("sink", () -> new HarmfulEffect(0x344D78)); + public static final DeferredHolder CHOKE = EFFECTS.register("choke", () -> new HarmfulEffect(0x737C81)); + private ModEffects() {} + public static void register(IEventBus bus) { EFFECTS.register(bus); } + private static final class HarmfulEffect extends MobEffect { + HarmfulEffect(int color) { super(MobEffectCategory.HARMFUL, color); } + } +} diff --git a/src/wilderness/java/org/polaris2023/wildwind/wilderness/effect/WildWindMobEffect.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/effect/WildWindMobEffect.java new file mode 100644 index 0000000..edb1aa3 --- /dev/null +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/effect/WildWindMobEffect.java @@ -0,0 +1,31 @@ +package org.polaris2023.wildwind.wilderness.effect; + +import net.minecraft.core.particles.ParticleOptions; +import net.minecraft.world.effect.MobEffect; +import net.minecraft.world.effect.MobEffectCategory; + +/** + * 用于拓宽 {@link MobEffect} 构造方法的访问权限 + */ +public class WildWindMobEffect extends MobEffect { + /** + * 创建一个基础生物效果喵~ + * + * @param category 效果分类喵~ + * @param color 效果颜色喵~ + */ + public WildWindMobEffect(MobEffectCategory category, int color) { + super(category, color); + } + + /** + * 创建一个带粒子效果的生物效果喵~ + * + * @param category 效果分类喵~ + * @param color 效果颜色喵~ + * @param particle 粒子效果喵~ + */ + public WildWindMobEffect(MobEffectCategory category, int color, ParticleOptions particle) { + super(category, color, particle); + } +} diff --git a/src/wilderness/java/org/polaris2023/wildwind/wilderness/entity/ModEntityTypeTags.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/entity/ModEntityTypeTags.java new file mode 100644 index 0000000..d2a8a85 --- /dev/null +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/entity/ModEntityTypeTags.java @@ -0,0 +1,20 @@ +package org.polaris2023.wildwind.wilderness.entity; + +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.Identifier; +import net.minecraft.tags.TagKey; +import net.minecraft.world.entity.EntityType; +import org.polaris2023.wildwind.wilderness.WildernessMod; + +/** Exact entity-type lists, shared by the server and client through data-pack tags. */ +public final class ModEntityTypeTags { + public static final TagKey> WATER_BREATHING = create("water_breathing"); + public static final TagKey> SINK_AFFECTED = create("sink_affected"); + public static final TagKey> CHOKE_AFFECTED = create("choke_affected"); + + private ModEntityTypeTags() {} + + private static TagKey> create(String name) { + return TagKey.create(Registries.ENTITY_TYPE, Identifier.fromNamespaceAndPath(WildernessMod.MOD_ID, name)); + } +} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/entity/ModSpawnPlacementTypes.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/entity/ModSpawnPlacementTypes.java similarity index 97% rename from src/hfas/java/org/polaris2023/wildwind/hfas/entity/ModSpawnPlacementTypes.java rename to src/wilderness/java/org/polaris2023/wildwind/wilderness/entity/ModSpawnPlacementTypes.java index 9b6dfbf..a6e81fb 100644 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/entity/ModSpawnPlacementTypes.java +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/entity/ModSpawnPlacementTypes.java @@ -1,4 +1,4 @@ -package org.polaris2023.wildwind.hfas.entity; +package org.polaris2023.wildwind.wilderness.entity; import net.minecraft.core.BlockPos; import net.minecraft.tags.BlockTags; diff --git a/src/wilderness/java/org/polaris2023/wildwind/wilderness/entity/MuddyPig.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/entity/MuddyPig.java new file mode 100644 index 0000000..37ad3f5 --- /dev/null +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/entity/MuddyPig.java @@ -0,0 +1,39 @@ +package org.polaris2023.wildwind.wilderness.entity; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.Identifier; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.tags.TagKey; +import net.minecraft.util.RandomSource; +import net.minecraft.world.entity.AgeableMob; +import net.minecraft.world.entity.EntitySpawnReason; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.animal.pig.Pig; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.Block; +import org.jspecify.annotations.Nullable; +import org.polaris2023.wildwind.wilderness.WildernessMod; +import org.polaris2023.wildwind.wilderness.registry.ModEntities; + +/** Vanilla pig AI, food and adult/baby sounds with a distinct entity and offspring type. */ +public class MuddyPig extends Pig { + public static final TagKey SPAWNABLE_ON = TagKey.create(Registries.BLOCK, + Identifier.fromNamespaceAndPath(WildernessMod.MOD_ID, "muddy_pig_spawnable_on")); + + public MuddyPig(EntityType type, Level level) { + super(type, level); + } + + @Override + public @Nullable MuddyPig getBreedOffspring(ServerLevel level, AgeableMob partner) { + return ModEntities.MUDDY_PIG.get().create(level, EntitySpawnReason.BREEDING); + } + + public static boolean checkSpawnRules(EntityType type, LevelAccessor level, + EntitySpawnReason reason, BlockPos pos, RandomSource random) { + return level.getBlockState(pos.below()).is(SPAWNABLE_ON) + && (EntitySpawnReason.ignoresLightRequirements(reason) || isBrightEnoughToSpawn(level, pos)); + } +} diff --git a/src/wilderness/java/org/polaris2023/wildwind/wilderness/entity/ReachArrow.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/entity/ReachArrow.java new file mode 100644 index 0000000..ea8083f --- /dev/null +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/entity/ReachArrow.java @@ -0,0 +1,33 @@ +package org.polaris2023.wildwind.wilderness.entity; + +import net.minecraft.core.component.DataComponents; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.projectile.arrow.Arrow; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.enchantment.EnchantmentHelper; +import net.minecraft.world.level.Level; +import org.jspecify.annotations.Nullable; +import org.polaris2023.wildwind.wilderness.mixin.AbstractArrowAccessor; +import org.polaris2023.wildwind.wilderness.registry.ModEntities; + +/** Native arrow physics, potion application, persistence and 600-tick decay. */ +public class ReachArrow extends Arrow { + public ReachArrow(EntityType type, Level level) { + super(type, level); + setPickupItemStack(new ItemStack(org.polaris2023.wildwind.wilderness.registry.ModItems.TIPPED_ARROW.get())); + } + + public ReachArrow(Level level, double x, double y, double z, ItemStack ammo, @Nullable ItemStack weapon) { + this(ModEntities.REACH_ARROW.get(), level); + setPickupItemStack(ammo.copyWithCount(1)); + applyComponentsFromItemStack(ammo); + if (ammo.has(DataComponents.INTANGIBLE_PROJECTILE)) pickup = Pickup.CREATIVE_ONLY; + setPos(x, y, z); + if (weapon != null && level instanceof ServerLevel serverLevel) { + if (weapon.isEmpty()) throw new IllegalArgumentException("Empty arrow weapon"); + ((AbstractArrowAccessor) this).wildwind$setWeapon(weapon.copy()); + ((AbstractArrowAccessor) this).wildwind$setPiercing((byte) EnchantmentHelper.getPiercingCount(serverLevel, weapon, ammo)); + } + } +} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/entity/WindupAttackMob.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/entity/WindupAttackMob.java similarity index 97% rename from src/hfas/java/org/polaris2023/wildwind/hfas/entity/WindupAttackMob.java rename to src/wilderness/java/org/polaris2023/wildwind/wilderness/entity/WindupAttackMob.java index 881ea24..5f20f90 100644 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/entity/WindupAttackMob.java +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/entity/WindupAttackMob.java @@ -1,4 +1,4 @@ -package org.polaris2023.wildwind.hfas.entity; +package org.polaris2023.wildwind.wilderness.entity; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.LivingEntity; diff --git a/src/wilderness/java/org/polaris2023/wildwind/wilderness/entity/ai/goal/AlertOthersNearestAttackableTargetGoal.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/entity/ai/goal/AlertOthersNearestAttackableTargetGoal.java new file mode 100644 index 0000000..9b349cd --- /dev/null +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/entity/ai/goal/AlertOthersNearestAttackableTargetGoal.java @@ -0,0 +1,91 @@ +package org.polaris2023.wildwind.wilderness.entity.ai.goal; + +import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; +import net.minecraft.world.entity.EntitySelector; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.TamableAnimal; +import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal; +import net.minecraft.world.entity.ai.targeting.TargetingConditions; +import net.minecraft.world.phys.AABB; + +import javax.annotation.Nullable; +import java.util.Set; + +/** + * 警告最近可攻击对象的目标 + * @param 实体类型 + * @author huimanman + */ +public class AlertOthersNearestAttackableTargetGoal extends NearestAttackableTargetGoal { + @Nullable + private Set> toIgnoreAlert; + private double overrideFindEntityFollowDistance = -1.0; + + public AlertOthersNearestAttackableTargetGoal(Mob mob, Class targetType, boolean mustSee) { + super(mob, targetType, mustSee); + } + + public AlertOthersNearestAttackableTargetGoal(Mob mob, Class targetType, boolean mustSee, TargetingConditions.Selector targetPredicate) { + super(mob, targetType, mustSee, targetPredicate); + } + + public AlertOthersNearestAttackableTargetGoal(Mob mob, Class targetType, boolean mustSee, boolean mustReach) { + super(mob, targetType, mustSee, mustReach); + } + + public AlertOthersNearestAttackableTargetGoal(Mob mob, Class targetType, int randomInterval, boolean mustSee, boolean mustReach, @Nullable TargetingConditions.Selector targetPredicate) { + super(mob, targetType, randomInterval, mustSee, mustReach, targetPredicate); + } + + /** + * 覆写跟随距离 + * @param followDistance 跟随距离 + * @return 当前目标,用于链式修改 + */ + public AlertOthersNearestAttackableTargetGoal overrideFindEntityFollowDistance(double followDistance) { + this.overrideFindEntityFollowDistance = followDistance; + return this; + } + + @Override + public void start() { + super.start(); + if (this.target != null) this.alertOthers(); + } + + public AlertOthersNearestAttackableTargetGoal ignoreAlertOthers(Class... reinforcementTypes) { + this.toIgnoreAlert = new ObjectOpenHashSet<>(reinforcementTypes); + return this; + } + + protected void alertOthers() { + double followDistance = super.getFollowDistance(); + AABB alertBox = AABB.unitCubeFromLowerCorner(this.mob.position()).inflate(followDistance, 10.0, followDistance); + for (Mob mob : this.mob.level().getEntitiesOfClass(this.mob.getClass(), alertBox, EntitySelector.NO_SPECTATORS)) { + if (this.mob != mob && this.shouldAlert(mob)) { + if (this.toIgnoreAlert != null && this.toIgnoreAlert.contains(mob.getClass())) continue; + } + + this.alertOther(mob, this.target); + } + } + + protected boolean shouldAlert(Mob other) { + LivingEntity target = mob.getTarget(); + return target != null + && (!(this.mob instanceof TamableAnimal selfMob) || (selfMob.getOwner() == ((TamableAnimal) other).getOwner()) + && !this.mob.isAlliedTo(target)); + } + + protected void alertOther(Mob mob, @Nullable LivingEntity target) { + mob.setTarget(target); + } + + @Override + protected double getFollowDistance() { + return this.overrideFindEntityFollowDistance != -1.0 + ? this.overrideFindEntityFollowDistance + : super.getFollowDistance(); + } +} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/entity/ai/goal/ChargingMeleeAttackGoal.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/entity/ai/goal/ChargingMeleeAttackGoal.java similarity index 90% rename from src/hfas/java/org/polaris2023/wildwind/hfas/entity/ai/goal/ChargingMeleeAttackGoal.java rename to src/wilderness/java/org/polaris2023/wildwind/wilderness/entity/ai/goal/ChargingMeleeAttackGoal.java index 56d9176..abd281f 100644 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/entity/ai/goal/ChargingMeleeAttackGoal.java +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/entity/ai/goal/ChargingMeleeAttackGoal.java @@ -1,9 +1,9 @@ -package org.polaris2023.wildwind.hfas.entity.ai.goal; +package org.polaris2023.wildwind.wilderness.entity.ai.goal; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.PathfinderMob; import net.minecraft.world.entity.ai.goal.MeleeAttackGoal; -import org.polaris2023.wildwind.hfas.entity.WindupAttackMob; +import org.polaris2023.wildwind.wilderness.entity.WindupAttackMob; /** * 准备近战攻击目标 diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/entity/animal/Mudcrab.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/entity/animal/Mudcrab.java similarity index 98% rename from src/hfas/java/org/polaris2023/wildwind/hfas/entity/animal/Mudcrab.java rename to src/wilderness/java/org/polaris2023/wildwind/wilderness/entity/animal/Mudcrab.java index 92ec6a6..d42c80c 100644 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/entity/animal/Mudcrab.java +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/entity/animal/Mudcrab.java @@ -1,4 +1,4 @@ -package org.polaris2023.wildwind.hfas.entity.animal; +package org.polaris2023.wildwind.wilderness.entity.animal; import com.geckolib.animatable.GeoEntity; import com.geckolib.animatable.instance.AnimatableInstanceCache; @@ -65,12 +65,12 @@ import net.minecraft.world.phys.Vec3; import net.neoforged.neoforge.common.Tags; import net.neoforged.neoforge.fluids.FluidType; -import org.polaris2023.wildwind.hfas.entity.ModSpawnPlacementTypes; -import org.polaris2023.wildwind.hfas.entity.WindupAttackMob; -import org.polaris2023.wildwind.hfas.entity.ai.goal.ChargingMeleeAttackGoal; -import org.polaris2023.wildwind.hfas.registry.*; -import org.polaris2023.wildwind.hfas.tag.ModBlockTags; -import org.polaris2023.wildwind.hfas.tag.ModItemTags; +import org.polaris2023.wildwind.wilderness.entity.ModSpawnPlacementTypes; +import org.polaris2023.wildwind.wilderness.entity.WindupAttackMob; +import org.polaris2023.wildwind.wilderness.entity.ai.goal.ChargingMeleeAttackGoal; +import org.polaris2023.wildwind.wilderness.registry.*; +import org.polaris2023.wildwind.wilderness.tag.ModBlockTags; +import org.polaris2023.wildwind.wilderness.tag.ModItemTags; import org.slf4j.Logger; import javax.annotation.Nullable; @@ -564,7 +564,7 @@ public void loadFromBucketTag(CompoundTag tag) { */ @Override public ItemStack getBucketItemStack() { - return new ItemStack((ItemLike) ModItems.MUDCRAB_BUCKET); + return new ItemStack((ItemLike) org.polaris2023.wildwind.wilderness.registry.ModItems.MUDCRAB_BUCKET); } /** @@ -626,7 +626,7 @@ protected SoundEvent getSwimSound() { protected void ageBoundaryReached() { super.ageBoundaryReached(); if (!this.isBaby() && ((ServerLevel)this.level()).getServer().getGameRules().get(GameRules.MOB_DROPS)) { - this.spawnAtLocation((ServerLevel)this.level(), ModItems.CRAB_CLAW); + this.spawnAtLocation((ServerLevel)this.level(), org.polaris2023.wildwind.wilderness.registry.ModItems.CRAB_CLAW); } } diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/entity/animal/MudcrabVariant.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/entity/animal/MudcrabVariant.java similarity index 80% rename from src/hfas/java/org/polaris2023/wildwind/hfas/entity/animal/MudcrabVariant.java rename to src/wilderness/java/org/polaris2023/wildwind/wilderness/entity/animal/MudcrabVariant.java index 513e989..6766eda 100644 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/entity/animal/MudcrabVariant.java +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/entity/animal/MudcrabVariant.java @@ -1,4 +1,4 @@ -package org.polaris2023.wildwind.hfas.entity.animal; +package org.polaris2023.wildwind.wilderness.entity.animal; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; @@ -15,9 +15,9 @@ import net.minecraft.resources.ResourceKey; import net.minecraft.world.entity.animal.TemperatureVariants; import net.minecraft.world.entity.variant.*; -import org.polaris2023.wildwind.hfas.HFASMod; -import org.polaris2023.wildwind.hfas.registry.DatadrivenRegistryKey; -import org.polaris2023.wildwind.hfas.tag.ModBiomeTags; +import org.polaris2023.wildwind.wilderness.WildernessMod; +import org.polaris2023.wildwind.wilderness.registry.DatadrivenRegistryKey; +import org.polaris2023.wildwind.wilderness.tag.ModBiomeTags; import java.util.List; import java.util.function.Function; @@ -56,9 +56,9 @@ private static ResourceKey createKey(Identifier id) { } public static void bootstrapDatagen(BootstrapContext registry) { - registry.register(TEMPERATE, new MudcrabVariant(new ClientAsset.ResourceTexture(HFASMod.id("entity/mudcrab/temperate")), SpawnPrioritySelectors.fallback(0))); - registry.register(WARM, new MudcrabVariant(new ClientAsset.ResourceTexture(HFASMod.id("entity/mudcrab/warm")), SpawnPrioritySelectors.single(new BiomeCheck(registry.lookup(Registries.BIOME).getOrThrow(ModBiomeTags.EntityGen.MUDCRABS_WARM)), 1))); - registry.register(COLD, new MudcrabVariant(new ClientAsset.ResourceTexture(HFASMod.id("entity/mudcrab/cold")), SpawnPrioritySelectors.single(new BiomeCheck(registry.lookup(Registries.BIOME).getOrThrow(ModBiomeTags.EntityGen.MUDCRABS_COLD)), 1))); + registry.register(TEMPERATE, new MudcrabVariant(new ClientAsset.ResourceTexture(WildernessMod.id("entity/mudcrab/temperate")), SpawnPrioritySelectors.fallback(0))); + registry.register(WARM, new MudcrabVariant(new ClientAsset.ResourceTexture(WildernessMod.id("entity/mudcrab/warm")), SpawnPrioritySelectors.single(new BiomeCheck(registry.lookup(Registries.BIOME).getOrThrow(ModBiomeTags.EntityGen.MUDCRABS_WARM)), 1))); + registry.register(COLD, new MudcrabVariant(new ClientAsset.ResourceTexture(WildernessMod.id("entity/mudcrab/cold")), SpawnPrioritySelectors.single(new BiomeCheck(registry.lookup(Registries.BIOME).getOrThrow(ModBiomeTags.EntityGen.MUDCRABS_COLD)), 1))); } public static Holder lookup(RegistryAccess access, ResourceKey key){ diff --git a/src/wilderness/java/org/polaris2023/wildwind/wilderness/entity/animal/Piranha.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/entity/animal/Piranha.java new file mode 100644 index 0000000..3ddf5e4 --- /dev/null +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/entity/animal/Piranha.java @@ -0,0 +1,154 @@ +package org.polaris2023.wildwind.wilderness.entity.animal; + +import com.geckolib.animatable.GeoEntity; +import com.geckolib.animatable.instance.AnimatableInstanceCache; +import com.geckolib.animatable.manager.AnimatableManager; +import com.geckolib.animation.AnimationController; +import com.geckolib.animation.object.PlayState; +import com.geckolib.animation.state.AnimationTest; +import com.geckolib.constant.DefaultAnimations; +import com.geckolib.util.GeckoLibUtil; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.ai.attributes.AttributeSupplier; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.ai.goal.target.HurtByTargetGoal; +import net.minecraft.world.entity.animal.fish.AbstractFish; +import net.minecraft.world.entity.animal.fish.AbstractSchoolingFish; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.ItemLike; +import net.minecraft.world.level.Level; +import org.polaris2023.wildwind.wilderness.entity.WindupAttackMob; +import org.polaris2023.wildwind.wilderness.entity.ai.goal.AlertOthersNearestAttackableTargetGoal; +import org.polaris2023.wildwind.wilderness.entity.ai.goal.ChargingMeleeAttackGoal; +import org.polaris2023.wildwind.wilderness.registry.ModSoundEvents; + +import javax.annotation.Nullable; + +public class Piranha extends AbstractSchoolingFish implements WindupAttackMob, GeoEntity { + private final AnimatableInstanceCache geoCache = GeckoLibUtil.createInstanceCache(this); + private int preparingToAttack; + + public Piranha(EntityType entityType, Level level) { + super(entityType, level); + } + + public static AttributeSupplier.Builder createAttributes() { + return AbstractFish.createAttributes() + .add(Attributes.MOVEMENT_SPEED, 0.95) + .add(Attributes.FOLLOW_RANGE, 35.0) + .add(Attributes.MAX_HEALTH, 6.0) + .add(Attributes.ATTACK_DAMAGE, 3.0); + } + + @Override + protected void registerGoals() { + this.goalSelector.addGoal(1, new PiranhaAttackGoal(this, 2.0f, false)); + super.registerGoals(); + this.targetSelector.addGoal(0, new HurtByTargetGoal(this).setAlertOthers()); + this.targetSelector.addGoal(1, new AlertOthersNearestAttackableTargetGoal<>(this, Mob.class, true, + (entity, level) -> !(entity instanceof Piranha) && (entity.getHealth() <= entity.getMaxHealth() * 0.25)) + .overrideFindEntityFollowDistance(15.0) + ); + this.targetSelector.addGoal(1, new AlertOthersNearestAttackableTargetGoal<>(this, Player.class, true, + (entity, level) -> entity.getHealth() <= entity.getMaxHealth() * 0.25) + .overrideFindEntityFollowDistance(15.0) + ); + } + + @Override + public int getMaxSchoolSize() { + return 5; + } + + // WIP SOUND + @Override + protected SoundEvent getFlopSound() { + return SoundEvents.SALMON_FLOP; + } + + @Override + protected @Nullable SoundEvent getDeathSound() { + return ModSoundEvents.PIRANHA_DEATH.get(); + } + + protected SoundEvent getAttackSound() { + return ModSoundEvents.PIRANHA_ATTACK.get(); + } + + @Override + public ItemStack getBucketItemStack() { + return new ItemStack((ItemLike) org.polaris2023.wildwind.wilderness.registry.ModItems.PIRANHA_BUCKET); + } + + @Override + public void registerControllers(AnimatableManager.ControllerRegistrar controllers) { + controllers.add(new AnimationController<>("Move", 3, this::moveAnimController)); + controllers.add(new AnimationController<>("Attack", state -> PlayState.STOP) + .triggerableAnim("attack", DefaultAnimations.ATTACK_SWING) + ); + } + + protected PlayState moveAnimController(final AnimationTest state) { + return state.setAndContinue(this.isInWater() ? DefaultAnimations.SWIM : DefaultAnimations.IDLE); + } + + @Override + public AnimatableInstanceCache getAnimatableInstanceCache() { + return this.geoCache; + } + + @Override + public void setPreparingToAttackTick(int tick) { + this.preparingToAttack = tick; + } + + @Override + public int getPreparingToAttackTick() { + return this.preparingToAttack; + } + + @Override + public int getPreparationToAttackDuration() { + return 6; + } + + @Override + public boolean prepareAttack(LivingEntity entity) { + boolean result = WindupAttackMob.super.prepareAttack(entity); + if (result) { + this.triggerAnim("Attack", "attack"); + this.makeSound(this.getAttackSound()); + } + return result; + } + + @Override + public boolean canContinuePreparingAttack() { + return this.isInWater(); + } + + @Override + public void aiStep() { + super.aiStep(); + if (!this.level().isClientSide() && this.isAlive()) { + processPreparingAttack((ServerLevel) this.level(), this); + } + } + + protected static class PiranhaAttackGoal extends ChargingMeleeAttackGoal { + public PiranhaAttackGoal(Piranha mob, double speedModifier, boolean followingTargetEvenIfNotSeen) { + super(mob, speedModifier, followingTargetEvenIfNotSeen); + } + + @Override + public boolean canUse() { + return this.mob.isInWater() && super.canUse(); + } + } +} diff --git a/src/wilderness/java/org/polaris2023/wildwind/wilderness/event/AzaleaAndArrowEvents.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/event/AzaleaAndArrowEvents.java new file mode 100644 index 0000000..cb94e8b --- /dev/null +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/event/AzaleaAndArrowEvents.java @@ -0,0 +1,39 @@ +package org.polaris2023.wildwind.wilderness.event; + +import java.util.ArrayList; +import net.minecraft.resources.Identifier; +import net.minecraft.world.level.block.DispenserBlock; +import net.minecraft.world.level.storage.loot.entries.LootItem; +import net.minecraft.world.level.storage.loot.functions.SetPotionFunction; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent; +import net.neoforged.neoforge.event.LootTableLoadEvent; +import org.polaris2023.wildwind.wilderness.WildernessMod; +import org.polaris2023.wildwind.wilderness.mixin.LootPoolEntriesAccessor; +import org.polaris2023.wildwind.wilderness.mixin.LootTablePoolsAccessor; +import org.polaris2023.wildwind.wilderness.registry.ModPotions; + +@EventBusSubscriber(modid = WildernessMod.MOD_ID) +public final class AzaleaAndArrowEvents { + @SubscribeEvent + public static void setup(FMLCommonSetupEvent event) { + event.enqueueWork(() -> { + DispenserBlock.registerProjectileBehavior(org.polaris2023.wildwind.wilderness.registry.ModItems.TIPPED_ARROW.get()); + }); + } + + @SubscribeEvent + public static void gifts(LootTableLoadEvent event) { + if (!event.getName().equals(Identifier.withDefaultNamespace("gameplay/hero_of_the_village/fletcher_gift"))) return; + var pools = ((LootTablePoolsAccessor) event.getTable()).wildwind$pools(); + if (pools.isEmpty()) return; + // Extend the existing random choice, preserving other mods' entries and the original number of rolls. + var pool = (LootPoolEntriesAccessor) pools.getFirst(); + var entries = new ArrayList<>(pool.wildwind$entries()); + entries.add(LootItem.lootTableItem(org.polaris2023.wildwind.wilderness.registry.ModItems.TIPPED_ARROW.get()) + .apply(SetPotionFunction.setPotion(ModPotions.REACH)).build()); + pool.wildwind$setEntries(java.util.List.copyOf(entries)); + } + +} diff --git a/src/wilderness/java/org/polaris2023/wildwind/wilderness/event/CreativeContents.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/event/CreativeContents.java new file mode 100644 index 0000000..687db3b --- /dev/null +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/event/CreativeContents.java @@ -0,0 +1,27 @@ +package org.polaris2023.wildwind.wilderness.event; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.alchemy.PotionContents; +import org.polaris2023.wildwind.core.registry.ModCreativeTabs; +import org.polaris2023.wildwind.wilderness.WildernessMod; +import org.polaris2023.wildwind.wilderness.block.ModBlocks; +import org.polaris2023.wildwind.wilderness.registry.*; + +@EventBusSubscriber(modid = WildernessMod.MOD_ID) +public final class CreativeContents { + @SubscribeEvent public static void populate(BuildCreativeModeTabContentsEvent event) { + if (!event.getTabKey().equals(ModCreativeTabs.WILD_WIND.getKey())) return; + ModBlocks.ITEMS.getEntries().forEach(item -> event.accept(item.get())); + + ModItems.ITEMS.getEntries().stream().filter(item -> item != ModItems.TIPPED_ARROW).forEach(item -> event.accept(item.get())); + ModPotions.POTIONS.getEntries().forEach(potion -> { + event.accept(PotionContents.createItemStack(Items.POTION, potion)); + event.accept(PotionContents.createItemStack(Items.SPLASH_POTION, potion)); + event.accept(PotionContents.createItemStack(Items.LINGERING_POTION, potion)); + event.accept(org.polaris2023.wildwind.wilderness.arrow.ReachArrows.convert(PotionContents.createItemStack(Items.TIPPED_ARROW, potion))); + }); + + } +} diff --git a/src/wilderness/java/org/polaris2023/wildwind/wilderness/event/EntitiesHandler.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/event/EntitiesHandler.java new file mode 100644 index 0000000..d0ebdf4 --- /dev/null +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/event/EntitiesHandler.java @@ -0,0 +1,34 @@ +package org.polaris2023.wildwind.wilderness.event; + +import net.minecraft.world.level.levelgen.Heightmap; +import net.minecraft.world.entity.SpawnPlacementTypes; +import net.minecraft.world.entity.animal.fish.WaterAnimal; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.event.entity.EntityAttributeCreationEvent; +import net.neoforged.neoforge.event.entity.RegisterSpawnPlacementsEvent; +import org.polaris2023.wildwind.wilderness.entity.animal.Mudcrab; +import org.polaris2023.wildwind.wilderness.entity.animal.Piranha; +import org.polaris2023.wildwind.wilderness.entity.MuddyPig; +import net.minecraft.world.entity.animal.pig.Pig; +import org.polaris2023.wildwind.wilderness.registry.ModEntities; + +@EventBusSubscriber +public class EntitiesHandler { + @SubscribeEvent + static void onAttributeCreate(EntityAttributeCreationEvent event) { + event.put(ModEntities.MUDDY_PIG.get(), Pig.createAttributes().build()); + event.put(ModEntities.PIRANHA.get(), Piranha.createAttributes().build()); + event.put(ModEntities.MUDCRAB.get(), Mudcrab.createAttributes().build()); + } + + @SubscribeEvent + static void registerSpawnPlacements(RegisterSpawnPlacementsEvent event) { + event.register(ModEntities.MUDDY_PIG.get(), SpawnPlacementTypes.ON_GROUND, + Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, MuddyPig::checkSpawnRules, + RegisterSpawnPlacementsEvent.Operation.REPLACE); + event.register(ModEntities.MUDCRAB.get(), Mudcrab.SPAWN_PLACEMENT, Heightmap.Types.OCEAN_FLOOR, Mudcrab::checkMudcrabInWaterGroundSpawnRules, RegisterSpawnPlacementsEvent.Operation.REPLACE); + event.register(ModEntities.MUDCRAB.get(), Mudcrab::checkMudcrabOnGroundSpawnRules); + event.register(ModEntities.PIRANHA.get(), SpawnPlacementTypes.IN_WATER, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, WaterAnimal::checkSurfaceWaterAnimalSpawnRules, RegisterSpawnPlacementsEvent.Operation.REPLACE); + } +} diff --git a/src/wilderness/java/org/polaris2023/wildwind/wilderness/event/FuelHandler.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/event/FuelHandler.java new file mode 100644 index 0000000..b0889da --- /dev/null +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/event/FuelHandler.java @@ -0,0 +1,71 @@ +package org.polaris2023.wildwind.wilderness.event; + +import net.minecraft.world.item.Item; +import net.minecraft.world.level.block.Block; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent; +import net.neoforged.neoforge.event.furnace.FurnaceFuelBurnTimeEvent; +import org.polaris2023.wildwind.wilderness.WildernessMod; + +/** + * 燃料事件处理器 + * 为木质方块添加燃料功能 + * + * @author baka4n + * @since 2026/04/15 + */ +@EventBusSubscriber(modid = WildernessMod.MOD_ID) +public class FuelHandler { + + /** + * 燃料燃烧时间事件 + * 木质方块可作为燃料,燃烧300 tick(与原版木板相同) + */ + @SubscribeEvent + public static void onFuelBurnTime(FurnaceFuelBurnTimeEvent event) { + Item item = event.getItemStack().getItem(); + + // 检查是否是木质方块物品 + int burnTime = getWoodBurnTime(item); + if (burnTime > 0) { + event.setBurnTime(burnTime); + } + } + + /** + * 获取木质方块的燃烧时间 + */ + private static int getWoodBurnTime(Item item) { + // 焚烬木 - 300 tick(15秒) + if (isBlazeWoodItem(item)) return 300; + // 灵焰木 - 300 tick + if (isSoulWoodItem(item)) return 300; + // 杜鹃木 - 300 tick + + return 0; + } + + private static boolean isBlazeWoodItem(Item item) { + return item == org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_LOG.get().asItem() + || item == org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_WOOD.get().asItem() + || item == org.polaris2023.wildwind.wilderness.block.ModBlocks.STRIPPED_BLAZE_LOG.get().asItem() + || item == org.polaris2023.wildwind.wilderness.block.ModBlocks.STRIPPED_BLAZE_WOOD.get().asItem() + || item == org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_PLANKS.get().asItem() + || item == org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_SLAB.get().asItem() + || item == org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_FENCE.get().asItem() + || item == org.polaris2023.wildwind.wilderness.block.ModBlocks.BLAZE_FENCE_GATE.get().asItem(); + } + + private static boolean isSoulWoodItem(Item item) { + return item == org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_LOG.get().asItem() + || item == org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_WOOD.get().asItem() + || item == org.polaris2023.wildwind.wilderness.block.ModBlocks.STRIPPED_SOUL_LOG.get().asItem() + || item == org.polaris2023.wildwind.wilderness.block.ModBlocks.STRIPPED_SOUL_WOOD.get().asItem() + || item == org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_PLANKS.get().asItem() + || item == org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_SLAB.get().asItem() + || item == org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_FENCE.get().asItem() + || item == org.polaris2023.wildwind.wilderness.block.ModBlocks.SOUL_FENCE_GATE.get().asItem(); + } + +} diff --git a/src/wilderness/java/org/polaris2023/wildwind/wilderness/item/ModFoods.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/item/ModFoods.java new file mode 100644 index 0000000..fbcea60 --- /dev/null +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/item/ModFoods.java @@ -0,0 +1,31 @@ +package org.polaris2023.wildwind.wilderness.item; + +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.effect.MobEffects; +import net.minecraft.world.food.FoodProperties; +import net.minecraft.world.item.component.Consumable; +import net.minecraft.world.item.consume_effects.ApplyStatusEffectsConsumeEffect; + +public class ModFoods { + public static final FoodProperties PIRANHA = new FoodProperties.Builder() + .nutrition(2) + .saturationModifier(0.1F) + .build(); + + public static final Consumable PIRANHA_CONSUMABLE = Consumable.builder() + .onConsume(new ApplyStatusEffectsConsumeEffect(new MobEffectInstance(MobEffects.HUNGER, 600), 0.8f)) + .onConsume(new ApplyStatusEffectsConsumeEffect(new MobEffectInstance(MobEffects.UNLUCK, 600), 0.5f)) + .build(); + + public static final FoodProperties COOKED_PIRANHA = new FoodProperties.Builder() + .nutrition(6) + .saturationModifier(0.8F) + .build(); + + public static final Consumable COOKED_PIRANHA_CONSUMABLE = Consumable.builder() + .onConsume(new ApplyStatusEffectsConsumeEffect(new MobEffectInstance(MobEffects.UNLUCK, 300), 0.3f)) + .build(); + + private ModFoods() { + } +} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/item/OmniClawItem.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/item/OmniClawItem.java similarity index 95% rename from src/hfas/java/org/polaris2023/wildwind/hfas/item/OmniClawItem.java rename to src/wilderness/java/org/polaris2023/wildwind/wilderness/item/OmniClawItem.java index 2c4bd91..dc9f0bb 100644 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/item/OmniClawItem.java +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/item/OmniClawItem.java @@ -1,4 +1,4 @@ -package org.polaris2023.wildwind.hfas.item; +package org.polaris2023.wildwind.wilderness.item; import com.google.common.collect.Lists; import net.minecraft.core.BlockPos; @@ -32,10 +32,10 @@ import net.minecraft.world.level.block.state.BlockState; import net.neoforged.neoforge.common.ItemAbility; import net.neoforged.neoforge.common.extensions.IItemExtension; -import org.polaris2023.wildwind.hfas.HFASMod; -import org.polaris2023.wildwind.hfas.component.OmniClawTools; -import org.polaris2023.wildwind.hfas.registry.ModAttributes; -import org.polaris2023.wildwind.hfas.registry.ModDataComponents; +import org.polaris2023.wildwind.wilderness.WildernessMod; +import org.polaris2023.wildwind.wilderness.component.OmniClawTools; +import org.polaris2023.wildwind.wilderness.registry.ModAttributes; +import org.polaris2023.wildwind.wilderness.registry.ModDataComponents; import java.util.Optional; import java.util.function.Function; @@ -53,15 +53,15 @@ public class OmniClawItem extends Item { /** * 额外交互方块距离属性修饰符标识喵~ */ - public static final Identifier BLOCK_INTERACTION_RANGE_ID = HFASMod.id("omni_claw_block_interaction_range"); + public static final Identifier BLOCK_INTERACTION_RANGE_ID = WildernessMod.id("omni_claw_block_interaction_range"); /** * 额外交互实体距离属性修饰符标识喵~ */ - public static final Identifier ENTITY_INTERACTION_RANGE_ID = HFASMod.id("omni_claw_entity_interaction_range"); + public static final Identifier ENTITY_INTERACTION_RANGE_ID = WildernessMod.id("omni_claw_entity_interaction_range"); /** * 额外拾取物品距离属性修饰符标识喵~ */ - public static final Identifier EXTRA_ITEM_PICKUP_RANGE_ID = HFASMod.id("omni_claw_extra_item_pickup_range"); + public static final Identifier EXTRA_ITEM_PICKUP_RANGE_ID = WildernessMod.id("omni_claw_extra_item_pickup_range"); /** * 创建万用蟹钳物品喵~ @@ -404,4 +404,4 @@ private void playRemoveOneSound(Entity entity) { private void playInsertSound(Entity entity) { entity.playSound(SoundEvents.BUNDLE_INSERT, 0.8F, 0.8F + entity.level().getRandom().nextFloat() * 0.4F); } -} \ No newline at end of file +} diff --git a/src/wilderness/java/org/polaris2023/wildwind/wilderness/item/ReachArrowItem.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/item/ReachArrowItem.java new file mode 100644 index 0000000..2bb5464 --- /dev/null +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/item/ReachArrowItem.java @@ -0,0 +1,41 @@ +package org.polaris2023.wildwind.wilderness.item; + +import net.minecraft.core.Direction; +import net.minecraft.core.Position; +import net.minecraft.core.component.DataComponents; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.projectile.Projectile; +import net.minecraft.world.entity.projectile.arrow.AbstractArrow; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TippedArrowItem; +import net.minecraft.world.item.alchemy.PotionContents; +import net.minecraft.world.level.Level; +import org.jspecify.annotations.Nullable; +import org.polaris2023.wildwind.wilderness.entity.ReachArrow; +import org.polaris2023.wildwind.wilderness.registry.ModPotions; + +public class ReachArrowItem extends TippedArrowItem { + public ReachArrowItem(Properties properties) { + super(properties.component(DataComponents.POTION_CONTENTS, new PotionContents(ModPotions.REACH)) + .component(DataComponents.POTION_DURATION_SCALE, 0.125F)); + } + + @Override + public ItemStack getDefaultInstance() { + return new ItemStack(this); + } + + @Override + public AbstractArrow createArrow(Level level, ItemStack stack, LivingEntity owner, @Nullable ItemStack weapon) { + var arrow = new ReachArrow(level, owner.getX(), owner.getEyeY() - 0.1F, owner.getZ(), stack, weapon); + arrow.setOwner(owner); + return arrow; + } + + @Override + public Projectile asProjectile(Level level, Position position, ItemStack stack, Direction direction) { + var arrow = new ReachArrow(level, position.x(), position.y(), position.z(), stack, null); + arrow.pickup = AbstractArrow.Pickup.ALLOWED; + return arrow; + } +} diff --git a/src/wilderness/java/org/polaris2023/wildwind/wilderness/mixin/AbstractArrowAccessor.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/mixin/AbstractArrowAccessor.java new file mode 100644 index 0000000..b60b73b --- /dev/null +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/mixin/AbstractArrowAccessor.java @@ -0,0 +1,15 @@ +package org.polaris2023.wildwind.wilderness.mixin; + +import net.minecraft.world.entity.projectile.arrow.AbstractArrow; +import net.minecraft.world.item.ItemStack; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(AbstractArrow.class) +public interface AbstractArrowAccessor { + @org.spongepowered.asm.mixin.gen.Invoker("setPierceLevel") + void wildwind$setPiercing(byte level); + + @Accessor("firedFromWeapon") + void wildwind$setWeapon(ItemStack weapon); +} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/mixin/EnchantmentHelperMixin.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/mixin/EnchantmentHelperMixin.java similarity index 89% rename from src/hfas/java/org/polaris2023/wildwind/hfas/mixin/EnchantmentHelperMixin.java rename to src/wilderness/java/org/polaris2023/wildwind/wilderness/mixin/EnchantmentHelperMixin.java index 1ed9566..2fa4c45 100644 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/mixin/EnchantmentHelperMixin.java +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/mixin/EnchantmentHelperMixin.java @@ -1,11 +1,11 @@ -package org.polaris2023.wildwind.hfas.mixin; +package org.polaris2023.wildwind.wilderness.mixin; import com.llamalad7.mixinextras.sugar.Local; import net.minecraft.core.component.DataComponents; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.enchantment.EnchantmentHelper; import net.minecraft.world.item.enchantment.ItemEnchantments; -import org.polaris2023.wildwind.hfas.item.OmniClawItem; +import org.polaris2023.wildwind.wilderness.item.OmniClawItem; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.ModifyVariable; @@ -22,4 +22,4 @@ private static ItemEnchantments getRandomItemWithUnwarpOmniClaw(ItemEnchantments if (!tool.isEmpty()) enchantments = tool.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY); return enchantments; } -} \ No newline at end of file +} diff --git a/src/wilderness/java/org/polaris2023/wildwind/wilderness/mixin/EntityFluidMovementMixin.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/mixin/EntityFluidMovementMixin.java new file mode 100644 index 0000000..2416c4a --- /dev/null +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/mixin/EntityFluidMovementMixin.java @@ -0,0 +1,17 @@ +package org.polaris2023.wildwind.wilderness.mixin; + +import net.minecraft.world.entity.Entity; +import net.minecraft.world.phys.Vec3; +import org.polaris2023.wildwind.wilderness.effect.FluidEffects; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyVariable; + +@Mixin(Entity.class) +abstract class EntityFluidMovementMixin { + // Intercept the actual displacement, including swimming AI and bubble-column upward motion. + @ModifyVariable(method = "move", at = @At("HEAD"), argsOnly = true) + private Vec3 wildwind$preventRising(Vec3 movement) { + return FluidEffects.restrictMovement((Entity) (Object) this, movement); + } +} diff --git a/src/wilderness/java/org/polaris2023/wildwind/wilderness/mixin/IronGolemAirSupplyMixin.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/mixin/IronGolemAirSupplyMixin.java new file mode 100644 index 0000000..172ddc2 --- /dev/null +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/mixin/IronGolemAirSupplyMixin.java @@ -0,0 +1,27 @@ +package org.polaris2023.wildwind.wilderness.mixin; + +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.animal.golem.IronGolem; +import net.minecraft.world.level.Level; +import org.polaris2023.wildwind.wilderness.effect.ModEffects; +import org.polaris2023.wildwind.wilderness.entity.ModEntityTypeTags; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(IronGolem.class) +abstract class IronGolemAirSupplyMixin extends LivingEntity { + protected IronGolemAirSupplyMixin(EntityType type, Level level) { + super(type, level); + } + + @Inject(method = "decreaseAirSupply", at = @At("HEAD"), cancellable = true) + private void wildwind$chokeAirConsumption(int currentSupply, CallbackInfoReturnable cir) { + if (is(ModEntityTypeTags.CHOKE_AFFECTED) && hasEffect(ModEffects.CHOKE)) { + // Iron golems otherwise always return unchanged air, bypassing even Respiration's normal rule. + cir.setReturnValue(super.decreaseAirSupply(currentSupply)); + } + } +} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/mixin/ItemStackMixin.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/mixin/ItemStackMixin.java similarity index 88% rename from src/hfas/java/org/polaris2023/wildwind/hfas/mixin/ItemStackMixin.java rename to src/wilderness/java/org/polaris2023/wildwind/wilderness/mixin/ItemStackMixin.java index ffc746f..0d18b35 100644 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/mixin/ItemStackMixin.java +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/mixin/ItemStackMixin.java @@ -1,4 +1,4 @@ -package org.polaris2023.wildwind.hfas.mixin; +package org.polaris2023.wildwind.wilderness.mixin; import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; @@ -7,9 +7,9 @@ import com.llamalad7.mixinextras.sugar.ref.LocalRef; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; -import org.polaris2023.wildwind.hfas.component.OmniClawTools; -import org.polaris2023.wildwind.hfas.item.OmniClawItem; -import org.polaris2023.wildwind.hfas.registry.ModDataComponents; +import org.polaris2023.wildwind.wilderness.component.OmniClawTools; +import org.polaris2023.wildwind.wilderness.item.OmniClawItem; +import org.polaris2023.wildwind.wilderness.registry.ModDataComponents; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -49,4 +49,4 @@ private void omniClawShrinkTool(ItemStack instance, int decrement, Operation wildwind$entries(); + @Mutable @Accessor("entries") void wildwind$setEntries(List entries); +} diff --git a/src/wilderness/java/org/polaris2023/wildwind/wilderness/mixin/LootTablePoolsAccessor.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/mixin/LootTablePoolsAccessor.java new file mode 100644 index 0000000..4913f90 --- /dev/null +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/mixin/LootTablePoolsAccessor.java @@ -0,0 +1,12 @@ +package org.polaris2023.wildwind.wilderness.mixin; + +import java.util.List; +import net.minecraft.world.level.storage.loot.LootPool; +import net.minecraft.world.level.storage.loot.LootTable; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(LootTable.class) +public interface LootTablePoolsAccessor { + @Accessor("pools") List wildwind$pools(); +} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/mixin/MobMixin.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/mixin/MobMixin.java similarity index 72% rename from src/hfas/java/org/polaris2023/wildwind/hfas/mixin/MobMixin.java rename to src/wilderness/java/org/polaris2023/wildwind/wilderness/mixin/MobMixin.java index f8cb3e2..e01104b 100644 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/mixin/MobMixin.java +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/mixin/MobMixin.java @@ -1,13 +1,18 @@ -package org.polaris2023.wildwind.hfas.mixin; +package org.polaris2023.wildwind.wilderness.mixin; import com.llamalad7.mixinextras.sugar.Local; import net.minecraft.core.Vec3i; import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.ai.attributes.AttributeMap; -import org.polaris2023.wildwind.hfas.registry.ModAttributes; +import org.polaris2023.wildwind.wilderness.registry.ModAttributes; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.ModifyVariable; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; /** * 让生物的物品拾取范围受额外拾取距离属性加成的混入类喵~ @@ -15,6 +20,7 @@ @Mixin(Mob.class) public abstract class MobMixin { + @ModifyVariable(method = "aiStep", at = @At(value = "STORE", ordinal = 0)) private Vec3i reachMobEffectPickupRange(Vec3i vec3i) { Mob self = (Mob) (Object) this; @@ -29,4 +35,4 @@ private Vec3i reachMobEffectPickupRange(Vec3i vec3i) { return vec3i; } -} \ No newline at end of file +} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/mixin/PlayerMixin.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/mixin/PlayerMixin.java similarity index 92% rename from src/hfas/java/org/polaris2023/wildwind/hfas/mixin/PlayerMixin.java rename to src/wilderness/java/org/polaris2023/wildwind/wilderness/mixin/PlayerMixin.java index b689dd8..74c2a01 100644 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/mixin/PlayerMixin.java +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/mixin/PlayerMixin.java @@ -1,4 +1,4 @@ -package org.polaris2023.wildwind.hfas.mixin; +package org.polaris2023.wildwind.wilderness.mixin; import com.llamalad7.mixinextras.sugar.Local; import net.minecraft.world.entity.Entity; @@ -6,7 +6,7 @@ import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.phys.AABB; -import org.polaris2023.wildwind.hfas.registry.ModAttributes; +import org.polaris2023.wildwind.wilderness.registry.ModAttributes; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -33,4 +33,4 @@ private void reachMobEffectTouchItem(CallbackInfo ci, @Local(ordinal = 0) AABB a } } } -} \ No newline at end of file +} diff --git a/src/wilderness/java/org/polaris2023/wildwind/wilderness/mixin/ReachArrowCraftingMixin.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/mixin/ReachArrowCraftingMixin.java new file mode 100644 index 0000000..3fd2216 --- /dev/null +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/mixin/ReachArrowCraftingMixin.java @@ -0,0 +1,17 @@ +package org.polaris2023.wildwind.wilderness.mixin; + +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.ImbueRecipe; +import org.polaris2023.wildwind.wilderness.arrow.ReachArrows; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(ImbueRecipe.class) +public abstract class ReachArrowCraftingMixin { + @Inject(method = "assemble(Lnet/minecraft/world/item/crafting/CraftingInput;)Lnet/minecraft/world/item/ItemStack;", at = @At("RETURN"), cancellable = true) + private void wildwind$reachArrow(CallbackInfoReturnable cir) { + cir.setReturnValue(ReachArrows.convert(cir.getReturnValue())); + } +} diff --git a/src/wilderness/java/org/polaris2023/wildwind/wilderness/mixin/ReachArrowLootMixin.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/mixin/ReachArrowLootMixin.java new file mode 100644 index 0000000..391b3e8 --- /dev/null +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/mixin/ReachArrowLootMixin.java @@ -0,0 +1,18 @@ +package org.polaris2023.wildwind.wilderness.mixin; + +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.storage.loot.functions.SetRandomPotionFunction; +import net.minecraft.world.level.storage.loot.functions.SetPotionFunction; +import org.polaris2023.wildwind.wilderness.arrow.ReachArrows; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin({SetRandomPotionFunction.class, SetPotionFunction.class}) +public abstract class ReachArrowLootMixin { + @Inject(method = "run", at = @At("RETURN"), cancellable = true) + private void wildwind$reachArrow(CallbackInfoReturnable cir) { + cir.setReturnValue(ReachArrows.convert(cir.getReturnValue())); + } +} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/mixin/ServerPlayerGameModeMixin.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/mixin/ServerPlayerGameModeMixin.java similarity index 96% rename from src/hfas/java/org/polaris2023/wildwind/hfas/mixin/ServerPlayerGameModeMixin.java rename to src/wilderness/java/org/polaris2023/wildwind/wilderness/mixin/ServerPlayerGameModeMixin.java index 7a9292e..d8a7756 100644 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/mixin/ServerPlayerGameModeMixin.java +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/mixin/ServerPlayerGameModeMixin.java @@ -1,4 +1,4 @@ -package org.polaris2023.wildwind.hfas.mixin; +package org.polaris2023.wildwind.wilderness.mixin; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; @@ -12,7 +12,7 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; -import org.polaris2023.wildwind.hfas.item.OmniClawItem; +import org.polaris2023.wildwind.wilderness.item.OmniClawItem; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -47,4 +47,4 @@ private ItemStack handleBlockBreakOmniClawSelectTool(ServerPlayer instance, Oper OmniClawItem.chooseToolItemByBlock(stack, state); return stack; } -} \ No newline at end of file +} diff --git a/src/wilderness/java/org/polaris2023/wildwind/wilderness/mixin/WaterAnimalAirSupplyMixin.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/mixin/WaterAnimalAirSupplyMixin.java new file mode 100644 index 0000000..65ca4fe --- /dev/null +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/mixin/WaterAnimalAirSupplyMixin.java @@ -0,0 +1,17 @@ +package org.polaris2023.wildwind.wilderness.mixin; + +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.animal.axolotl.Axolotl; +import net.minecraft.world.entity.animal.fish.WaterAnimal; +import org.polaris2023.wildwind.wilderness.effect.FluidEffects; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyVariable; + +@Mixin({Axolotl.class, WaterAnimal.class}) +abstract class WaterAnimalAirSupplyMixin { + @ModifyVariable(method = "handleAirSupply", at = @At("HEAD"), argsOnly = true) + private int wildwind$accelerateLandDrying(int preTickAirSupply) { + return FluidEffects.airBeforeDrying((LivingEntity) (Object) this, preTickAirSupply); + } +} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/network/HFASNetwork.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/network/HFASNetwork.java similarity index 71% rename from src/hfas/java/org/polaris2023/wildwind/hfas/network/HFASNetwork.java rename to src/wilderness/java/org/polaris2023/wildwind/wilderness/network/HFASNetwork.java index 2b23805..4b1be9c 100644 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/network/HFASNetwork.java +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/network/HFASNetwork.java @@ -1,16 +1,16 @@ -package org.polaris2023.wildwind.hfas.network; +package org.polaris2023.wildwind.wilderness.network; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent; import net.neoforged.neoforge.network.registration.PayloadRegistrar; -import org.polaris2023.wildwind.hfas.HFASMod; -import org.polaris2023.wildwind.hfas.network.payload.ServerBoundSelectOmniClawItemPayload; +import org.polaris2023.wildwind.wilderness.WildernessMod; +import org.polaris2023.wildwind.wilderness.network.payload.ServerBoundSelectOmniClawItemPayload; /** * 模组网络负载注册入口喵~ */ -@EventBusSubscriber(modid = HFASMod.MOD_ID) +@EventBusSubscriber(modid = WildernessMod.MOD_ID) public class HFASNetwork { @SubscribeEvent @@ -25,4 +25,4 @@ static void register(RegisterPayloadHandlersEvent event) { private HFASNetwork() { } -} \ No newline at end of file +} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/network/payload/ServerBoundSelectOmniClawItemPayload.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/network/payload/ServerBoundSelectOmniClawItemPayload.java similarity index 86% rename from src/hfas/java/org/polaris2023/wildwind/hfas/network/payload/ServerBoundSelectOmniClawItemPayload.java rename to src/wilderness/java/org/polaris2023/wildwind/wilderness/network/payload/ServerBoundSelectOmniClawItemPayload.java index 1c672b6..ea2a446 100644 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/network/payload/ServerBoundSelectOmniClawItemPayload.java +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/network/payload/ServerBoundSelectOmniClawItemPayload.java @@ -1,4 +1,4 @@ -package org.polaris2023.wildwind.hfas.network.payload; +package org.polaris2023.wildwind.wilderness.network.payload; import io.netty.buffer.ByteBuf; import net.minecraft.network.codec.ByteBufCodecs; @@ -7,9 +7,9 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.neoforged.neoforge.network.handling.IPayloadContext; -import org.polaris2023.wildwind.hfas.HFASMod; -import org.polaris2023.wildwind.hfas.component.OmniClawTools; -import org.polaris2023.wildwind.hfas.registry.ModDataComponents; +import org.polaris2023.wildwind.wilderness.WildernessMod; +import org.polaris2023.wildwind.wilderness.component.OmniClawTools; +import org.polaris2023.wildwind.wilderness.registry.ModDataComponents; /** * 客户端通知服务端切换全能蟹钳选中工具的网络负载喵~ @@ -21,7 +21,7 @@ public record ServerBoundSelectOmniClawItemPayload(int slot, int index) implemen /** * 当前负载的类型标识喵~ */ - public static final Type TYPE = new Type<>(HFASMod.id("select_omni_claw_item")); + public static final Type TYPE = new Type<>(WildernessMod.id("select_omni_claw_item")); /** * 当前负载的流编解码器喵~ */ @@ -70,4 +70,4 @@ public void handle(IPayloadContext context) { stack.set(ModDataComponents.OMNI_CLAW_TOOLS.get(), mutableTools.toImmutable()); } -} \ No newline at end of file +} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/registry/DatadrivenRegistryKey.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/registry/DatadrivenRegistryKey.java similarity index 63% rename from src/hfas/java/org/polaris2023/wildwind/hfas/registry/DatadrivenRegistryKey.java rename to src/wilderness/java/org/polaris2023/wildwind/wilderness/registry/DatadrivenRegistryKey.java index 250ae7f..271ee42 100644 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/registry/DatadrivenRegistryKey.java +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/registry/DatadrivenRegistryKey.java @@ -1,9 +1,9 @@ -package org.polaris2023.wildwind.hfas.registry; +package org.polaris2023.wildwind.wilderness.registry; import net.minecraft.core.Registry; import net.minecraft.resources.ResourceKey; -import org.polaris2023.wildwind.hfas.HFASMod; -import org.polaris2023.wildwind.hfas.entity.animal.MudcrabVariant; +import org.polaris2023.wildwind.wilderness.WildernessMod; +import org.polaris2023.wildwind.wilderness.entity.animal.MudcrabVariant; //内容请注册到mod主类的Datapack注册事件中 public class DatadrivenRegistryKey { @@ -14,6 +14,6 @@ public class DatadrivenRegistryKey { private static ResourceKey> createRegistryKey(String name) { - return ResourceKey.createRegistryKey(HFASMod.id(name)); + return ResourceKey.createRegistryKey(WildernessMod.id(name)); } } diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/registry/ModAttributes.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/registry/ModAttributes.java similarity index 84% rename from src/hfas/java/org/polaris2023/wildwind/hfas/registry/ModAttributes.java rename to src/wilderness/java/org/polaris2023/wildwind/wilderness/registry/ModAttributes.java index c802b34..fd1537f 100644 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/registry/ModAttributes.java +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/registry/ModAttributes.java @@ -1,4 +1,4 @@ -package org.polaris2023.wildwind.hfas.registry; +package org.polaris2023.wildwind.wilderness.registry; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.world.entity.ai.attributes.Attribute; @@ -9,7 +9,7 @@ import net.neoforged.neoforge.event.entity.EntityAttributeModificationEvent; import net.neoforged.neoforge.registries.DeferredHolder; import net.neoforged.neoforge.registries.DeferredRegister; -import org.polaris2023.wildwind.hfas.HFASMod; +import org.polaris2023.wildwind.wilderness.WildernessMod; /** * 注册模组属性喵~ @@ -17,19 +17,19 @@ * 26.2 迁移说明:旧仓库通过 LivingEntityMixin 向全体生物基础属性表追加属性, * 现改用 NeoForge 的 EntityAttributeModificationEvent 实现同等效果(涵盖玩家)。 */ -@EventBusSubscriber(modid = HFASMod.MOD_ID) +@EventBusSubscriber(modid = WildernessMod.MOD_ID) public class ModAttributes { /** * 模组属性延迟注册器喵~ */ - public static final DeferredRegister ATTRIBUTES = DeferredRegister.create(BuiltInRegistries.ATTRIBUTE, HFASMod.MOD_ID); + public static final DeferredRegister ATTRIBUTES = DeferredRegister.create(BuiltInRegistries.ATTRIBUTE, WildernessMod.MOD_ID); /** * 额外物品拾取距离属性喵~ */ public static final DeferredHolder EXTRA_ITEM_PICKUP_RANGE = ATTRIBUTES.register("extra_item_pickup_range", () -> new RangedAttribute( - "attributes.ww_hfas.extra_item_pickup_range", + "attributes.wild_wind_wilderness.extra_item_pickup_range", 0.0, 0.0, 10.0 @@ -56,4 +56,4 @@ public static void register(IEventBus modBus) { static void addAttributesToLivingEntities(EntityAttributeModificationEvent event) { event.getTypes().forEach(type -> event.add(type, EXTRA_ITEM_PICKUP_RANGE)); } -} \ No newline at end of file +} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/registry/ModDataComponents.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/registry/ModDataComponents.java similarity index 68% rename from src/hfas/java/org/polaris2023/wildwind/hfas/registry/ModDataComponents.java rename to src/wilderness/java/org/polaris2023/wildwind/wilderness/registry/ModDataComponents.java index f36f99f..f63f1d4 100644 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/registry/ModDataComponents.java +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/registry/ModDataComponents.java @@ -1,4 +1,4 @@ -package org.polaris2023.wildwind.hfas.registry; +package org.polaris2023.wildwind.wilderness.registry; import net.minecraft.core.Holder; import net.minecraft.core.component.DataComponentType; @@ -7,13 +7,12 @@ import net.neoforged.bus.api.IEventBus; import net.neoforged.neoforge.registries.DeferredHolder; import net.neoforged.neoforge.registries.DeferredRegister; -import org.polaris2023.wildwind.hfas.HFASMod; -import org.polaris2023.wildwind.hfas.component.ArrowComponent; -import org.polaris2023.wildwind.hfas.component.OmniClawTools; -import org.polaris2023.wildwind.hfas.entity.animal.MudcrabVariant; +import org.polaris2023.wildwind.wilderness.WildernessMod; +import org.polaris2023.wildwind.wilderness.component.OmniClawTools; +import org.polaris2023.wildwind.wilderness.entity.animal.MudcrabVariant; public class ModDataComponents { - public static final DeferredRegister.DataComponents REGISTER = DeferredRegister.createDataComponents(Registries.DATA_COMPONENT_TYPE, HFASMod.MOD_ID); + public static final DeferredRegister.DataComponents REGISTER = DeferredRegister.createDataComponents(Registries.DATA_COMPONENT_TYPE, WildernessMod.MOD_ID); public static final DeferredHolder, DataComponentType>> MUDCRAB_VARIANT = REGISTER.registerComponentType("mubcrab_variant", builder -> @@ -23,10 +22,7 @@ public class ModDataComponents { /** * 箭矢组件 - 存储箭羽、箭杆、箭头类型 */ - public static final DeferredHolder, DataComponentType> ARROW_COMPONENT = - REGISTER.registerComponentType("arrow_component", builder -> - builder.persistent(ArrowComponent.CODEC).networkSynchronized(ArrowComponent.STREAM_CODEC) - ); + /** * 万用蟹钳工具集合数据组件喵~ diff --git a/src/wilderness/java/org/polaris2023/wildwind/wilderness/registry/ModEntities.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/registry/ModEntities.java new file mode 100644 index 0000000..7007d28 --- /dev/null +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/registry/ModEntities.java @@ -0,0 +1,54 @@ +package org.polaris2023.wildwind.wilderness.registry; + +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.MobCategory; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.neoforge.registries.DeferredHolder; +import net.neoforged.neoforge.registries.DeferredRegister; +import org.polaris2023.wildwind.wilderness.WildernessMod; +import org.polaris2023.wildwind.wilderness.client.eventsub.EntitiesClientHandler; +import org.polaris2023.wildwind.wilderness.entity.animal.Mudcrab; +import org.polaris2023.wildwind.wilderness.entity.animal.Piranha; +import org.polaris2023.wildwind.wilderness.entity.MuddyPig; + + +public class ModEntities { + public static final DeferredRegister.Entities ENTITY_TYPES = + DeferredRegister.createEntities(WildernessMod.MOD_ID); + + public static final DeferredHolder, EntityType> REACH_ARROW = + ENTITY_TYPES.registerEntityType("arrow", org.polaris2023.wildwind.wilderness.entity.ReachArrow::new, MobCategory.MISC, + builder -> builder.noLootTable().sized(0.5F, 0.5F).eyeHeight(0.13F).clientTrackingRange(4).updateInterval(20)); + + private ModEntities() { + } + + public static final DeferredHolder, EntityType> MUDDY_PIG = + ENTITY_TYPES.registerEntityType("muddy_pig", MuddyPig::new, MobCategory.CREATURE, + builder -> builder.sized(0.9F, 0.9F).passengerAttachments(0.86875F).clientTrackingRange(10)); + + //泥沼蟹实体类型 + public static final DeferredHolder, EntityType> MUDCRAB = + ENTITY_TYPES.registerEntityType("mudcrab", Mudcrab::new, MobCategory.WATER_CREATURE, + builder -> builder.sized(0.5F, 0.55F).clientTrackingRange(8) + ); + + //食人鱼实体类型 + public static final DeferredHolder, EntityType> PIRANHA = + ENTITY_TYPES.registerEntityType("piranha", Piranha::new, MobCategory.WATER_AMBIENT, + builder -> builder.sized(0.7F, 0.4F).eyeHeight(0.26F) + ); + + /** + * 向模组事件总线注册实体类型喵~ + * + * @see EntitiesClientHandler EntitiesClientEvent 实体客户端渲染绑定 + * @see org.polaris2023.wildwind.wilderness.event.EntitiesHandler EntitiesHandler 实体服务端信息(attribute等绑定) + * + * @param modBus 模组事件总线喵~ + */ + public static void register(IEventBus modBus) { + ENTITY_TYPES.register(modBus); + } + +} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/registry/ModEntityDataSerializers.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/registry/ModEntityDataSerializers.java similarity index 82% rename from src/hfas/java/org/polaris2023/wildwind/hfas/registry/ModEntityDataSerializers.java rename to src/wilderness/java/org/polaris2023/wildwind/wilderness/registry/ModEntityDataSerializers.java index f8f98ca..7d0d306 100644 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/registry/ModEntityDataSerializers.java +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/registry/ModEntityDataSerializers.java @@ -1,12 +1,12 @@ -package org.polaris2023.wildwind.hfas.registry; +package org.polaris2023.wildwind.wilderness.registry; import net.minecraft.core.Holder; import net.minecraft.network.syncher.EntityDataSerializer; import net.neoforged.bus.api.IEventBus; import net.neoforged.neoforge.registries.DeferredRegister; import net.neoforged.neoforge.registries.NeoForgeRegistries; -import org.polaris2023.wildwind.hfas.HFASMod; -import org.polaris2023.wildwind.hfas.entity.animal.MudcrabVariant; +import org.polaris2023.wildwind.wilderness.WildernessMod; +import org.polaris2023.wildwind.wilderness.entity.animal.MudcrabVariant; import java.util.function.Supplier; @@ -17,7 +17,7 @@ public class ModEntityDataSerializers { /** * 实体数据序列化器延迟注册器喵~ */ - public static final DeferredRegister> ENTITY_DATA_SERIALIZERS = DeferredRegister.create(NeoForgeRegistries.ENTITY_DATA_SERIALIZERS, HFASMod.MOD_ID); + public static final DeferredRegister> ENTITY_DATA_SERIALIZERS = DeferredRegister.create(NeoForgeRegistries.ENTITY_DATA_SERIALIZERS, WildernessMod.MOD_ID); /** * 泥沼蟹变种实体数据序列化器喵~ diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/registry/ModItems.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/registry/ModItems.java similarity index 60% rename from src/hfas/java/org/polaris2023/wildwind/hfas/registry/ModItems.java rename to src/wilderness/java/org/polaris2023/wildwind/wilderness/registry/ModItems.java index c8622f3..d32e374 100644 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/registry/ModItems.java +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/registry/ModItems.java @@ -1,4 +1,4 @@ -package org.polaris2023.wildwind.hfas.registry; +package org.polaris2023.wildwind.wilderness.registry; import net.minecraft.core.Holder; import net.minecraft.sounds.SoundEvents; @@ -10,33 +10,33 @@ import net.neoforged.bus.api.IEventBus; import net.neoforged.neoforge.registries.DeferredItem; import net.neoforged.neoforge.registries.DeferredRegister; -import org.polaris2023.wildwind.hfas.HFASMod; -import org.polaris2023.wildwind.hfas.component.OmniClawTools; -import org.polaris2023.wildwind.hfas.item.OmniClawItem; +import org.polaris2023.wildwind.wilderness.WildernessMod; +import org.polaris2023.wildwind.wilderness.component.OmniClawTools; +import org.polaris2023.wildwind.wilderness.item.ModFoods; +import org.polaris2023.wildwind.wilderness.item.OmniClawItem; import java.util.function.Function; +import java.util.List; public class ModItems { - public static final DeferredRegister.Items ITEMS = DeferredRegister.createItems(HFASMod.MOD_ID); - - //泥沼蟹刷怪蛋 + public static final DeferredRegister.Items ITEMS = DeferredRegister.createItems(WildernessMod.MOD_ID); + public static final DeferredItem TIPPED_ARROW = + register("tipped_arrow", org.polaris2023.wildwind.wilderness.item.ReachArrowItem::new); + public static final DeferredItem MUDDY_PIG_SPAWN_EGG = registerMobEgg("muddy_pig_spawn_egg", ModEntities.MUDDY_PIG); public static final DeferredItem MUDCRAB_SPAWN_EGG = registerMobEgg("mudcrab_spawn_egg",ModEntities.MUDCRAB); - - //泥沼蟹桶 public static final DeferredItem MUDCRAB_BUCKET = register("mudcrab_bucket",p -> new MobBucketItem(ModEntities.MUDCRAB.get(),Fluids.WATER,SoundEvents.BUCKET_EMPTY,p)); - - //蟹钳 public static final DeferredItem CRAB_CLAW = register("crab_claw"); - - - //万用蟹钳 + public static final DeferredItem PIRANHA = register("piranha", p -> new Item(p.food(ModFoods.PIRANHA, ModFoods.PIRANHA_CONSUMABLE))); + public static final DeferredItem COOKED_PIRANHA = register("cooked_piranha", p -> new Item(p.food(ModFoods.COOKED_PIRANHA, ModFoods.COOKED_PIRANHA_CONSUMABLE))); + public static final DeferredItem PIRANHA_SPAWN_EGG = registerMobEgg("piranha_spawn_egg", ModEntities.PIRANHA); + public static final DeferredItem PIRANHA_BUCKET = register("piranha_bucket", p -> new MobBucketItem(ModEntities.PIRANHA.get(), Fluids.WATER, SoundEvents.BUCKET_EMPTY_FISH, p)); + public static final DeferredItem FANG = register("fang"); public static final DeferredItem OMNI_CLAW = register("omni_claw", p -> new OmniClawItem( p.stacksTo(1) .attributes(OmniClawItem.createAttributes()) .component(ModDataComponents.OMNI_CLAW_TOOLS.get(), OmniClawTools.EMPTY) )); - public static void register(IEventBus modBus) { ITEMS.register(modBus); } diff --git a/src/wilderness/java/org/polaris2023/wildwind/wilderness/registry/ModMobEffects.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/registry/ModMobEffects.java new file mode 100644 index 0000000..b61c872 --- /dev/null +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/registry/ModMobEffects.java @@ -0,0 +1,62 @@ +package org.polaris2023.wildwind.wilderness.registry; + +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.world.effect.MobEffect; +import net.minecraft.world.effect.MobEffectCategory; +import net.minecraft.world.entity.ai.attributes.AttributeModifier; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.neoforge.registries.DeferredHolder; +import net.neoforged.neoforge.registries.DeferredRegister; +import org.polaris2023.wildwind.wilderness.WildernessMod; +import org.polaris2023.wildwind.wilderness.registry.ModAttributes; +import org.polaris2023.wildwind.wilderness.effect.WildWindMobEffect; + +/** + * 注册模组状态效果喵~ + */ +public class ModMobEffects { + /** + * 状态效果延迟注册器喵~ + */ + public static final DeferredRegister MOB_EFFECTS = + DeferredRegister.create(BuiltInRegistries.MOB_EFFECT, WildernessMod.MOD_ID); + + /** + * 延展状态效果喵~ + */ + public static final DeferredHolder REACH = + MOB_EFFECTS.register("reach", + () -> new WildWindMobEffect(MobEffectCategory.BENEFICIAL, 0xFF3F7E8E) + .addAttributeModifier( + Attributes.BLOCK_INTERACTION_RANGE, + WildernessMod.id("effect.reach"), + 2.0, + AttributeModifier.Operation.ADD_VALUE + ) + .addAttributeModifier( + Attributes.ENTITY_INTERACTION_RANGE, + WildernessMod.id("effect.reach"), + 2.0, + AttributeModifier.Operation.ADD_VALUE + ) + .addAttributeModifier( + ModAttributes.EXTRA_ITEM_PICKUP_RANGE, + WildernessMod.id("effect.reach"), + 2.0, + AttributeModifier.Operation.ADD_VALUE + ) + ); + + /** + * 向模组事件总线注册状态效果喵~ + * + * @param modBus 模组事件总线喵~ + */ + public static void register(IEventBus modBus) { + MOB_EFFECTS.register(modBus); + } + + private ModMobEffects() { + } +} diff --git a/src/wilderness/java/org/polaris2023/wildwind/wilderness/registry/ModPotions.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/registry/ModPotions.java new file mode 100644 index 0000000..7c976cc --- /dev/null +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/registry/ModPotions.java @@ -0,0 +1,72 @@ +package org.polaris2023.wildwind.wilderness.registry; + +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.alchemy.Potion; +import net.minecraft.world.item.alchemy.PotionBrewing; +import net.minecraft.world.item.alchemy.Potions; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.event.brewing.RegisterBrewingRecipesEvent; +import net.neoforged.neoforge.registries.DeferredHolder; +import net.neoforged.neoforge.registries.DeferredRegister; +import org.polaris2023.wildwind.wilderness.WildernessMod; + +/** + * 注册模组药水并处理酿造配方喵~ + */ +@EventBusSubscriber(modid = WildernessMod.MOD_ID) +public class ModPotions { + /** + * 药水延迟注册器喵~ + */ + public static final DeferredRegister POTIONS = + DeferredRegister.create(BuiltInRegistries.POTION, WildernessMod.MOD_ID); + + /** + * 延展药水喵~ + */ + public static final DeferredHolder REACH = + POTIONS.register("reach", () -> new Potion("reach", new MobEffectInstance(ModMobEffects.REACH, 3600))); + /** + * 长效延展药水喵~ + */ + public static final DeferredHolder LONG_REACH = + POTIONS.register("long_reach", () -> new Potion("long_reach", new MobEffectInstance(ModMobEffects.REACH, 9600))); + + /** + * 向模组事件总线注册药水喵~ + * + * @param modBus 模组事件总线喵~ + */ + public static void register(IEventBus modBus) { + POTIONS.register(modBus); + } + + /** + * 注册药水酿造配方喵~ + * + * @param event 酿造配方注册事件喵~ + */ + @SubscribeEvent + static void registerBrewingRecipes(RegisterBrewingRecipesEvent event) { + PotionBrewing.Builder builder = event.getBuilder(); + + builder.addMix( + Potions.AWKWARD, + org.polaris2023.wildwind.wilderness.registry.ModItems.CRAB_CLAW.get(), + ModPotions.REACH + ); + + builder.addMix( + ModPotions.REACH, + Items.REDSTONE, + ModPotions.LONG_REACH + ); + } + + private ModPotions() { + } +} diff --git a/src/wilderness/java/org/polaris2023/wildwind/wilderness/registry/ModSoundEvents.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/registry/ModSoundEvents.java new file mode 100644 index 0000000..80aa6a4 --- /dev/null +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/registry/ModSoundEvents.java @@ -0,0 +1,30 @@ +package org.polaris2023.wildwind.wilderness.registry; + +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.sounds.SoundEvent; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.neoforge.registries.DeferredHolder; +import net.neoforged.neoforge.registries.DeferredRegister; +import org.polaris2023.wildwind.wilderness.WildernessMod; + +public class ModSoundEvents { + public static final DeferredRegister SOUND_EVENTS = + DeferredRegister.create(BuiltInRegistries.SOUND_EVENT, WildernessMod.MOD_ID); + + public static final DeferredHolder PIRANHA_ATTACK = SOUND_EVENTS.register( + "entity.piranha.attack", + SoundEvent::createVariableRangeEvent + ); + + public static final DeferredHolder PIRANHA_DEATH = SOUND_EVENTS.register( + "entity.piranha.death", + SoundEvent::createVariableRangeEvent + ); + + public static void register(IEventBus modEventBus) { + SOUND_EVENTS.register(modEventBus); + } + + private ModSoundEvents() { + } +} diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/tag/ModBiomeTags.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/tag/ModBiomeTags.java similarity index 69% rename from src/hfas/java/org/polaris2023/wildwind/hfas/tag/ModBiomeTags.java rename to src/wilderness/java/org/polaris2023/wildwind/wilderness/tag/ModBiomeTags.java index 500c841..a947df9 100644 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/tag/ModBiomeTags.java +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/tag/ModBiomeTags.java @@ -1,9 +1,9 @@ -package org.polaris2023.wildwind.hfas.tag; +package org.polaris2023.wildwind.wilderness.tag; import net.minecraft.core.registries.Registries; import net.minecraft.tags.TagKey; import net.minecraft.world.level.biome.Biome; -import org.polaris2023.wildwind.hfas.HFASMod; +import org.polaris2023.wildwind.wilderness.WildernessMod; /** * 定义模组群系标签喵~ @@ -19,6 +19,10 @@ interface EntityGen{ * 会生成冷色变种泥沼蟹的群系标签喵~ */ TagKey MUDCRABS_COLD = create("entity_spawn/mudcrab/cold"); + /** + * 会生成食人鱼的群系标签喵~ + */ + TagKey PIRANHA_SPAWNS = create("entity_spawn/piranha"); } /** @@ -28,6 +32,6 @@ interface EntityGen{ * @return 群系标签键喵~ */ static TagKey create(String path) { - return TagKey.create(Registries.BIOME, HFASMod.id(path)); + return TagKey.create(Registries.BIOME, WildernessMod.id(path)); } } diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/tag/ModBlockTags.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/tag/ModBlockTags.java similarity index 54% rename from src/hfas/java/org/polaris2023/wildwind/hfas/tag/ModBlockTags.java rename to src/wilderness/java/org/polaris2023/wildwind/wilderness/tag/ModBlockTags.java index 7ef4a96..38532c3 100644 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/tag/ModBlockTags.java +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/tag/ModBlockTags.java @@ -1,9 +1,9 @@ -package org.polaris2023.wildwind.hfas.tag; +package org.polaris2023.wildwind.wilderness.tag; import net.minecraft.tags.BlockTags; import net.minecraft.tags.TagKey; import net.minecraft.world.level.block.Block; -import org.polaris2023.wildwind.hfas.HFASMod; +import org.polaris2023.wildwind.wilderness.WildernessMod; /** * 定义模组方块标签喵~ @@ -12,14 +12,14 @@ public interface ModBlockTags { interface EntityAbout { //泥沼蟹可在其上生成的方块标签喵~ - TagKey MUDCRAB_SPAWNABLE_ON = BlockTags.create(HFASMod.id("entity/mudcrab/spawnable_on")); + TagKey MUDCRAB_SPAWNABLE_ON = BlockTags.create(WildernessMod.id("entity/mudcrab/spawnable_on")); //泥沼蟹可在水下地面生成的方块标签喵~ - TagKey MUDCRAB_SPAWNABLE_IN_WATER_GROUND = BlockTags.create(HFASMod.id("entity/mudcrab/spawnable_in_water_ground")); + TagKey MUDCRAB_SPAWNABLE_IN_WATER_GROUND = BlockTags.create(WildernessMod.id("entity/mudcrab/spawnable_in_water_ground")); //泥沼蟹偏好游荡的方块标签喵~ - TagKey MUDCRAB_PREFERRED_WANDER_BLOCKS = BlockTags.create(HFASMod.id("entity/mudcrab/preferred_wander_blocks")); + TagKey MUDCRAB_PREFERRED_WANDER_BLOCKS = BlockTags.create(WildernessMod.id("entity/mudcrab/preferred_wander_blocks")); //蜘蛛卵 - TagKey SPIDER_COCOONS = BlockTags.create(HFASMod.id("spider_cocoons")); + TagKey SPIDER_COCOONS = BlockTags.create(WildernessMod.id("spider_cocoons")); } } diff --git a/src/hfas/java/org/polaris2023/wildwind/hfas/tag/ModItemTags.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/tag/ModItemTags.java similarity index 55% rename from src/hfas/java/org/polaris2023/wildwind/hfas/tag/ModItemTags.java rename to src/wilderness/java/org/polaris2023/wildwind/wilderness/tag/ModItemTags.java index 29cea11..8390280 100644 --- a/src/hfas/java/org/polaris2023/wildwind/hfas/tag/ModItemTags.java +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/tag/ModItemTags.java @@ -1,9 +1,9 @@ -package org.polaris2023.wildwind.hfas.tag; +package org.polaris2023.wildwind.wilderness.tag; import net.minecraft.tags.ItemTags; import net.minecraft.tags.TagKey; import net.minecraft.world.item.Item; -import org.polaris2023.wildwind.hfas.HFASMod; +import org.polaris2023.wildwind.wilderness.WildernessMod; /** * 定义模组物品标签喵~ @@ -12,5 +12,5 @@ public interface ModItemTags { /** * 泥沼蟹食物的物品标签喵~ */ - TagKey MUDCRAB_FOOD = ItemTags.create(HFASMod.id("mudcrab_food")); + TagKey MUDCRAB_FOOD = ItemTags.create(WildernessMod.id("mudcrab_food")); } diff --git a/src/wilderness/java/org/polaris2023/wildwind/wilderness/worldgen/ModTreeGrowers.java b/src/wilderness/java/org/polaris2023/wildwind/wilderness/worldgen/ModTreeGrowers.java new file mode 100644 index 0000000..a3a6c01 --- /dev/null +++ b/src/wilderness/java/org/polaris2023/wildwind/wilderness/worldgen/ModTreeGrowers.java @@ -0,0 +1,10 @@ +package org.polaris2023.wildwind.wilderness.worldgen; +import net.minecraft.world.level.block.grower.TreeGrower; +import net.minecraft.resources.ResourceKey; +import net.minecraft.core.registries.Registries; +import java.util.Optional; +import org.polaris2023.wildwind.wilderness.WildernessMod; +public final class ModTreeGrowers { + public static final TreeGrower BLAZE = new TreeGrower("wild_wind_wilderness:blaze", Optional.empty(), Optional.of(ResourceKey.create(Registries.CONFIGURED_FEATURE, WildernessMod.id("blaze_tree"))), Optional.empty()); + public static final TreeGrower SOUL = new TreeGrower("wild_wind_wilderness:soul", Optional.empty(), Optional.of(ResourceKey.create(Registries.CONFIGURED_FEATURE, WildernessMod.id("soul_tree"))), Optional.empty()); +} diff --git a/src/hfas/resources/META-INF/accesstransformer.cfg b/src/wilderness/resources/META-INF/accesstransformer.cfg similarity index 100% rename from src/hfas/resources/META-INF/accesstransformer.cfg rename to src/wilderness/resources/META-INF/accesstransformer.cfg diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/blaze_button.json b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/blaze_button.json new file mode 100644 index 0000000..865fa4b --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/blaze_button.json @@ -0,0 +1,118 @@ +{ + "variants": { + "face=ceiling,facing=east,powered=false": { + "model": "wild_wind_wilderness:block/blaze_button", + "x": 180, + "y": 270 + }, + "face=ceiling,facing=east,powered=true": { + "model": "wild_wind_wilderness:block/blaze_button_pressed", + "x": 180, + "y": 270 + }, + "face=ceiling,facing=north,powered=false": { + "model": "wild_wind_wilderness:block/blaze_button", + "x": 180, + "y": 180 + }, + "face=ceiling,facing=north,powered=true": { + "model": "wild_wind_wilderness:block/blaze_button_pressed", + "x": 180, + "y": 180 + }, + "face=ceiling,facing=south,powered=false": { + "model": "wild_wind_wilderness:block/blaze_button", + "x": 180 + }, + "face=ceiling,facing=south,powered=true": { + "model": "wild_wind_wilderness:block/blaze_button_pressed", + "x": 180 + }, + "face=ceiling,facing=west,powered=false": { + "model": "wild_wind_wilderness:block/blaze_button", + "x": 180, + "y": 90 + }, + "face=ceiling,facing=west,powered=true": { + "model": "wild_wind_wilderness:block/blaze_button_pressed", + "x": 180, + "y": 90 + }, + "face=floor,facing=east,powered=false": { + "model": "wild_wind_wilderness:block/blaze_button", + "y": 90 + }, + "face=floor,facing=east,powered=true": { + "model": "wild_wind_wilderness:block/blaze_button_pressed", + "y": 90 + }, + "face=floor,facing=north,powered=false": { + "model": "wild_wind_wilderness:block/blaze_button" + }, + "face=floor,facing=north,powered=true": { + "model": "wild_wind_wilderness:block/blaze_button_pressed" + }, + "face=floor,facing=south,powered=false": { + "model": "wild_wind_wilderness:block/blaze_button", + "y": 180 + }, + "face=floor,facing=south,powered=true": { + "model": "wild_wind_wilderness:block/blaze_button_pressed", + "y": 180 + }, + "face=floor,facing=west,powered=false": { + "model": "wild_wind_wilderness:block/blaze_button", + "y": 270 + }, + "face=floor,facing=west,powered=true": { + "model": "wild_wind_wilderness:block/blaze_button_pressed", + "y": 270 + }, + "face=wall,facing=east,powered=false": { + "model": "wild_wind_wilderness:block/blaze_button", + "uvlock": true, + "x": 90, + "y": 90 + }, + "face=wall,facing=east,powered=true": { + "model": "wild_wind_wilderness:block/blaze_button_pressed", + "uvlock": true, + "x": 90, + "y": 90 + }, + "face=wall,facing=north,powered=false": { + "model": "wild_wind_wilderness:block/blaze_button", + "uvlock": true, + "x": 90 + }, + "face=wall,facing=north,powered=true": { + "model": "wild_wind_wilderness:block/blaze_button_pressed", + "uvlock": true, + "x": 90 + }, + "face=wall,facing=south,powered=false": { + "model": "wild_wind_wilderness:block/blaze_button", + "uvlock": true, + "x": 90, + "y": 180 + }, + "face=wall,facing=south,powered=true": { + "model": "wild_wind_wilderness:block/blaze_button_pressed", + "uvlock": true, + "x": 90, + "y": 180 + }, + "face=wall,facing=west,powered=false": { + "model": "wild_wind_wilderness:block/blaze_button", + "uvlock": true, + "x": 90, + "y": 270 + }, + "face=wall,facing=west,powered=true": { + "model": "wild_wind_wilderness:block/blaze_button_pressed", + "uvlock": true, + "x": 90, + "y": 270 + } + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/blaze_door.json b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/blaze_door.json new file mode 100644 index 0000000..af8c56d --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/blaze_door.json @@ -0,0 +1,124 @@ +{ + "variants": { + "facing=east,half=lower,hinge=left,open=false": { + "model": "wild_wind_wilderness:block/blaze_door_bottom_left" + }, + "facing=east,half=lower,hinge=left,open=true": { + "model": "wild_wind_wilderness:block/blaze_door_bottom_left_open", + "y": 90 + }, + "facing=east,half=lower,hinge=right,open=false": { + "model": "wild_wind_wilderness:block/blaze_door_bottom_right" + }, + "facing=east,half=lower,hinge=right,open=true": { + "model": "wild_wind_wilderness:block/blaze_door_bottom_right_open", + "y": 270 + }, + "facing=east,half=upper,hinge=left,open=false": { + "model": "wild_wind_wilderness:block/blaze_door_top_left" + }, + "facing=east,half=upper,hinge=left,open=true": { + "model": "wild_wind_wilderness:block/blaze_door_top_left_open", + "y": 90 + }, + "facing=east,half=upper,hinge=right,open=false": { + "model": "wild_wind_wilderness:block/blaze_door_top_right" + }, + "facing=east,half=upper,hinge=right,open=true": { + "model": "wild_wind_wilderness:block/blaze_door_top_right_open", + "y": 270 + }, + "facing=north,half=lower,hinge=left,open=false": { + "model": "wild_wind_wilderness:block/blaze_door_bottom_left", + "y": 270 + }, + "facing=north,half=lower,hinge=left,open=true": { + "model": "wild_wind_wilderness:block/blaze_door_bottom_left_open" + }, + "facing=north,half=lower,hinge=right,open=false": { + "model": "wild_wind_wilderness:block/blaze_door_bottom_right", + "y": 270 + }, + "facing=north,half=lower,hinge=right,open=true": { + "model": "wild_wind_wilderness:block/blaze_door_bottom_right_open", + "y": 180 + }, + "facing=north,half=upper,hinge=left,open=false": { + "model": "wild_wind_wilderness:block/blaze_door_top_left", + "y": 270 + }, + "facing=north,half=upper,hinge=left,open=true": { + "model": "wild_wind_wilderness:block/blaze_door_top_left_open" + }, + "facing=north,half=upper,hinge=right,open=false": { + "model": "wild_wind_wilderness:block/blaze_door_top_right", + "y": 270 + }, + "facing=north,half=upper,hinge=right,open=true": { + "model": "wild_wind_wilderness:block/blaze_door_top_right_open", + "y": 180 + }, + "facing=south,half=lower,hinge=left,open=false": { + "model": "wild_wind_wilderness:block/blaze_door_bottom_left", + "y": 90 + }, + "facing=south,half=lower,hinge=left,open=true": { + "model": "wild_wind_wilderness:block/blaze_door_bottom_left_open", + "y": 180 + }, + "facing=south,half=lower,hinge=right,open=false": { + "model": "wild_wind_wilderness:block/blaze_door_bottom_right", + "y": 90 + }, + "facing=south,half=lower,hinge=right,open=true": { + "model": "wild_wind_wilderness:block/blaze_door_bottom_right_open" + }, + "facing=south,half=upper,hinge=left,open=false": { + "model": "wild_wind_wilderness:block/blaze_door_top_left", + "y": 90 + }, + "facing=south,half=upper,hinge=left,open=true": { + "model": "wild_wind_wilderness:block/blaze_door_top_left_open", + "y": 180 + }, + "facing=south,half=upper,hinge=right,open=false": { + "model": "wild_wind_wilderness:block/blaze_door_top_right", + "y": 90 + }, + "facing=south,half=upper,hinge=right,open=true": { + "model": "wild_wind_wilderness:block/blaze_door_top_right_open" + }, + "facing=west,half=lower,hinge=left,open=false": { + "model": "wild_wind_wilderness:block/blaze_door_bottom_left", + "y": 180 + }, + "facing=west,half=lower,hinge=left,open=true": { + "model": "wild_wind_wilderness:block/blaze_door_bottom_left_open", + "y": 270 + }, + "facing=west,half=lower,hinge=right,open=false": { + "model": "wild_wind_wilderness:block/blaze_door_bottom_right", + "y": 180 + }, + "facing=west,half=lower,hinge=right,open=true": { + "model": "wild_wind_wilderness:block/blaze_door_bottom_right_open", + "y": 90 + }, + "facing=west,half=upper,hinge=left,open=false": { + "model": "wild_wind_wilderness:block/blaze_door_top_left", + "y": 180 + }, + "facing=west,half=upper,hinge=left,open=true": { + "model": "wild_wind_wilderness:block/blaze_door_top_left_open", + "y": 270 + }, + "facing=west,half=upper,hinge=right,open=false": { + "model": "wild_wind_wilderness:block/blaze_door_top_right", + "y": 180 + }, + "facing=west,half=upper,hinge=right,open=true": { + "model": "wild_wind_wilderness:block/blaze_door_top_right_open", + "y": 90 + } + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/blaze_fence.json b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/blaze_fence.json new file mode 100644 index 0000000..8afb5ec --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/blaze_fence.json @@ -0,0 +1,48 @@ +{ + "multipart": [ + { + "apply": { + "model": "wild_wind_wilderness:block/blaze_fence_post" + } + }, + { + "apply": { + "model": "wild_wind_wilderness:block/blaze_fence_side", + "uvlock": true + }, + "when": { + "north": "true" + } + }, + { + "apply": { + "model": "wild_wind_wilderness:block/blaze_fence_side", + "uvlock": true, + "y": 90 + }, + "when": { + "east": "true" + } + }, + { + "apply": { + "model": "wild_wind_wilderness:block/blaze_fence_side", + "uvlock": true, + "y": 180 + }, + "when": { + "south": "true" + } + }, + { + "apply": { + "model": "wild_wind_wilderness:block/blaze_fence_side", + "uvlock": true, + "y": 270 + }, + "when": { + "west": "true" + } + } + ] +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/blaze_fence_gate.json b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/blaze_fence_gate.json new file mode 100644 index 0000000..c9c0c65 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/blaze_fence_gate.json @@ -0,0 +1,80 @@ +{ + "variants": { + "facing=east,in_wall=false,open=false": { + "model": "wild_wind_wilderness:block/blaze_fence_gate", + "uvlock": true, + "y": 270 + }, + "facing=east,in_wall=false,open=true": { + "model": "wild_wind_wilderness:block/blaze_fence_gate_open", + "uvlock": true, + "y": 270 + }, + "facing=east,in_wall=true,open=false": { + "model": "wild_wind_wilderness:block/blaze_fence_gate_wall", + "uvlock": true, + "y": 270 + }, + "facing=east,in_wall=true,open=true": { + "model": "wild_wind_wilderness:block/blaze_fence_gate_wall_open", + "uvlock": true, + "y": 270 + }, + "facing=north,in_wall=false,open=false": { + "model": "wild_wind_wilderness:block/blaze_fence_gate", + "uvlock": true, + "y": 180 + }, + "facing=north,in_wall=false,open=true": { + "model": "wild_wind_wilderness:block/blaze_fence_gate_open", + "uvlock": true, + "y": 180 + }, + "facing=north,in_wall=true,open=false": { + "model": "wild_wind_wilderness:block/blaze_fence_gate_wall", + "uvlock": true, + "y": 180 + }, + "facing=north,in_wall=true,open=true": { + "model": "wild_wind_wilderness:block/blaze_fence_gate_wall_open", + "uvlock": true, + "y": 180 + }, + "facing=south,in_wall=false,open=false": { + "model": "wild_wind_wilderness:block/blaze_fence_gate", + "uvlock": true + }, + "facing=south,in_wall=false,open=true": { + "model": "wild_wind_wilderness:block/blaze_fence_gate_open", + "uvlock": true + }, + "facing=south,in_wall=true,open=false": { + "model": "wild_wind_wilderness:block/blaze_fence_gate_wall", + "uvlock": true + }, + "facing=south,in_wall=true,open=true": { + "model": "wild_wind_wilderness:block/blaze_fence_gate_wall_open", + "uvlock": true + }, + "facing=west,in_wall=false,open=false": { + "model": "wild_wind_wilderness:block/blaze_fence_gate", + "uvlock": true, + "y": 90 + }, + "facing=west,in_wall=false,open=true": { + "model": "wild_wind_wilderness:block/blaze_fence_gate_open", + "uvlock": true, + "y": 90 + }, + "facing=west,in_wall=true,open=false": { + "model": "wild_wind_wilderness:block/blaze_fence_gate_wall", + "uvlock": true, + "y": 90 + }, + "facing=west,in_wall=true,open=true": { + "model": "wild_wind_wilderness:block/blaze_fence_gate_wall_open", + "uvlock": true, + "y": 90 + } + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/blaze_leaves.json b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/blaze_leaves.json new file mode 100644 index 0000000..6926d22 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/blaze_leaves.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "wild_wind_wilderness:block/blaze_leaves" + } + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/blaze_log.json b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/blaze_log.json new file mode 100644 index 0000000..298540f --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/blaze_log.json @@ -0,0 +1,16 @@ +{ + "variants": { + "axis=x": { + "model": "wild_wind_wilderness:block/blaze_log_horizontal", + "x": 90, + "y": 90 + }, + "axis=y": { + "model": "wild_wind_wilderness:block/blaze_log" + }, + "axis=z": { + "model": "wild_wind_wilderness:block/blaze_log_horizontal", + "x": 90 + } + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/blaze_planks.json b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/blaze_planks.json new file mode 100644 index 0000000..743e44c --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/blaze_planks.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "wild_wind_wilderness:block/blaze_planks" + } + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/blaze_pressure_plate.json b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/blaze_pressure_plate.json new file mode 100644 index 0000000..2da9ceb --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/blaze_pressure_plate.json @@ -0,0 +1,10 @@ +{ + "variants": { + "powered=false": { + "model": "wild_wind_wilderness:block/blaze_pressure_plate" + }, + "powered=true": { + "model": "wild_wind_wilderness:block/blaze_pressure_plate_down" + } + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/blaze_sapling.json b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/blaze_sapling.json new file mode 100644 index 0000000..b2d26c7 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/blaze_sapling.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "wild_wind_wilderness:block/blaze_sapling" + } + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/blaze_slab.json b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/blaze_slab.json new file mode 100644 index 0000000..41dc685 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/blaze_slab.json @@ -0,0 +1,13 @@ +{ + "variants": { + "type=bottom": { + "model": "wild_wind_wilderness:block/blaze_slab" + }, + "type=double": { + "model": "wild_wind_wilderness:block/blaze_planks" + }, + "type=top": { + "model": "wild_wind_wilderness:block/blaze_slab_top" + } + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/blaze_stairs.json b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/blaze_stairs.json new file mode 100644 index 0000000..bca7c2c --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/blaze_stairs.json @@ -0,0 +1,209 @@ +{ + "variants": { + "facing=east,half=bottom,shape=inner_left": { + "model": "wild_wind_wilderness:block/blaze_stairs_inner", + "uvlock": true, + "y": 270 + }, + "facing=east,half=bottom,shape=inner_right": { + "model": "wild_wind_wilderness:block/blaze_stairs_inner" + }, + "facing=east,half=bottom,shape=outer_left": { + "model": "wild_wind_wilderness:block/blaze_stairs_outer", + "uvlock": true, + "y": 270 + }, + "facing=east,half=bottom,shape=outer_right": { + "model": "wild_wind_wilderness:block/blaze_stairs_outer" + }, + "facing=east,half=bottom,shape=straight": { + "model": "wild_wind_wilderness:block/blaze_stairs" + }, + "facing=east,half=top,shape=inner_left": { + "model": "wild_wind_wilderness:block/blaze_stairs_inner", + "uvlock": true, + "x": 180 + }, + "facing=east,half=top,shape=inner_right": { + "model": "wild_wind_wilderness:block/blaze_stairs_inner", + "uvlock": true, + "x": 180, + "y": 90 + }, + "facing=east,half=top,shape=outer_left": { + "model": "wild_wind_wilderness:block/blaze_stairs_outer", + "uvlock": true, + "x": 180 + }, + "facing=east,half=top,shape=outer_right": { + "model": "wild_wind_wilderness:block/blaze_stairs_outer", + "uvlock": true, + "x": 180, + "y": 90 + }, + "facing=east,half=top,shape=straight": { + "model": "wild_wind_wilderness:block/blaze_stairs", + "uvlock": true, + "x": 180 + }, + "facing=north,half=bottom,shape=inner_left": { + "model": "wild_wind_wilderness:block/blaze_stairs_inner", + "uvlock": true, + "y": 180 + }, + "facing=north,half=bottom,shape=inner_right": { + "model": "wild_wind_wilderness:block/blaze_stairs_inner", + "uvlock": true, + "y": 270 + }, + "facing=north,half=bottom,shape=outer_left": { + "model": "wild_wind_wilderness:block/blaze_stairs_outer", + "uvlock": true, + "y": 180 + }, + "facing=north,half=bottom,shape=outer_right": { + "model": "wild_wind_wilderness:block/blaze_stairs_outer", + "uvlock": true, + "y": 270 + }, + "facing=north,half=bottom,shape=straight": { + "model": "wild_wind_wilderness:block/blaze_stairs", + "uvlock": true, + "y": 270 + }, + "facing=north,half=top,shape=inner_left": { + "model": "wild_wind_wilderness:block/blaze_stairs_inner", + "uvlock": true, + "x": 180, + "y": 270 + }, + "facing=north,half=top,shape=inner_right": { + "model": "wild_wind_wilderness:block/blaze_stairs_inner", + "uvlock": true, + "x": 180 + }, + "facing=north,half=top,shape=outer_left": { + "model": "wild_wind_wilderness:block/blaze_stairs_outer", + "uvlock": true, + "x": 180, + "y": 270 + }, + "facing=north,half=top,shape=outer_right": { + "model": "wild_wind_wilderness:block/blaze_stairs_outer", + "uvlock": true, + "x": 180 + }, + "facing=north,half=top,shape=straight": { + "model": "wild_wind_wilderness:block/blaze_stairs", + "uvlock": true, + "x": 180, + "y": 270 + }, + "facing=south,half=bottom,shape=inner_left": { + "model": "wild_wind_wilderness:block/blaze_stairs_inner" + }, + "facing=south,half=bottom,shape=inner_right": { + "model": "wild_wind_wilderness:block/blaze_stairs_inner", + "uvlock": true, + "y": 90 + }, + "facing=south,half=bottom,shape=outer_left": { + "model": "wild_wind_wilderness:block/blaze_stairs_outer" + }, + "facing=south,half=bottom,shape=outer_right": { + "model": "wild_wind_wilderness:block/blaze_stairs_outer", + "uvlock": true, + "y": 90 + }, + "facing=south,half=bottom,shape=straight": { + "model": "wild_wind_wilderness:block/blaze_stairs", + "uvlock": true, + "y": 90 + }, + "facing=south,half=top,shape=inner_left": { + "model": "wild_wind_wilderness:block/blaze_stairs_inner", + "uvlock": true, + "x": 180, + "y": 90 + }, + "facing=south,half=top,shape=inner_right": { + "model": "wild_wind_wilderness:block/blaze_stairs_inner", + "uvlock": true, + "x": 180, + "y": 180 + }, + "facing=south,half=top,shape=outer_left": { + "model": "wild_wind_wilderness:block/blaze_stairs_outer", + "uvlock": true, + "x": 180, + "y": 90 + }, + "facing=south,half=top,shape=outer_right": { + "model": "wild_wind_wilderness:block/blaze_stairs_outer", + "uvlock": true, + "x": 180, + "y": 180 + }, + "facing=south,half=top,shape=straight": { + "model": "wild_wind_wilderness:block/blaze_stairs", + "uvlock": true, + "x": 180, + "y": 90 + }, + "facing=west,half=bottom,shape=inner_left": { + "model": "wild_wind_wilderness:block/blaze_stairs_inner", + "uvlock": true, + "y": 90 + }, + "facing=west,half=bottom,shape=inner_right": { + "model": "wild_wind_wilderness:block/blaze_stairs_inner", + "uvlock": true, + "y": 180 + }, + "facing=west,half=bottom,shape=outer_left": { + "model": "wild_wind_wilderness:block/blaze_stairs_outer", + "uvlock": true, + "y": 90 + }, + "facing=west,half=bottom,shape=outer_right": { + "model": "wild_wind_wilderness:block/blaze_stairs_outer", + "uvlock": true, + "y": 180 + }, + "facing=west,half=bottom,shape=straight": { + "model": "wild_wind_wilderness:block/blaze_stairs", + "uvlock": true, + "y": 180 + }, + "facing=west,half=top,shape=inner_left": { + "model": "wild_wind_wilderness:block/blaze_stairs_inner", + "uvlock": true, + "x": 180, + "y": 180 + }, + "facing=west,half=top,shape=inner_right": { + "model": "wild_wind_wilderness:block/blaze_stairs_inner", + "uvlock": true, + "x": 180, + "y": 270 + }, + "facing=west,half=top,shape=outer_left": { + "model": "wild_wind_wilderness:block/blaze_stairs_outer", + "uvlock": true, + "x": 180, + "y": 180 + }, + "facing=west,half=top,shape=outer_right": { + "model": "wild_wind_wilderness:block/blaze_stairs_outer", + "uvlock": true, + "x": 180, + "y": 270 + }, + "facing=west,half=top,shape=straight": { + "model": "wild_wind_wilderness:block/blaze_stairs", + "uvlock": true, + "x": 180, + "y": 180 + } + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/blaze_trapdoor.json b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/blaze_trapdoor.json new file mode 100644 index 0000000..d237422 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/blaze_trapdoor.json @@ -0,0 +1,58 @@ +{ + "variants": { + "facing=east,half=bottom,open=false": { + "model": "wild_wind_wilderness:block/blaze_trapdoor_bottom" + }, + "facing=east,half=bottom,open=true": { + "model": "wild_wind_wilderness:block/blaze_trapdoor_open", + "y": 90 + }, + "facing=east,half=top,open=false": { + "model": "wild_wind_wilderness:block/blaze_trapdoor_top" + }, + "facing=east,half=top,open=true": { + "model": "wild_wind_wilderness:block/blaze_trapdoor_open", + "y": 90 + }, + "facing=north,half=bottom,open=false": { + "model": "wild_wind_wilderness:block/blaze_trapdoor_bottom" + }, + "facing=north,half=bottom,open=true": { + "model": "wild_wind_wilderness:block/blaze_trapdoor_open" + }, + "facing=north,half=top,open=false": { + "model": "wild_wind_wilderness:block/blaze_trapdoor_top" + }, + "facing=north,half=top,open=true": { + "model": "wild_wind_wilderness:block/blaze_trapdoor_open" + }, + "facing=south,half=bottom,open=false": { + "model": "wild_wind_wilderness:block/blaze_trapdoor_bottom" + }, + "facing=south,half=bottom,open=true": { + "model": "wild_wind_wilderness:block/blaze_trapdoor_open", + "y": 180 + }, + "facing=south,half=top,open=false": { + "model": "wild_wind_wilderness:block/blaze_trapdoor_top" + }, + "facing=south,half=top,open=true": { + "model": "wild_wind_wilderness:block/blaze_trapdoor_open", + "y": 180 + }, + "facing=west,half=bottom,open=false": { + "model": "wild_wind_wilderness:block/blaze_trapdoor_bottom" + }, + "facing=west,half=bottom,open=true": { + "model": "wild_wind_wilderness:block/blaze_trapdoor_open", + "y": 270 + }, + "facing=west,half=top,open=false": { + "model": "wild_wind_wilderness:block/blaze_trapdoor_top" + }, + "facing=west,half=top,open=true": { + "model": "wild_wind_wilderness:block/blaze_trapdoor_open", + "y": 270 + } + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/blaze_wood.json b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/blaze_wood.json new file mode 100644 index 0000000..27b64df --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/blaze_wood.json @@ -0,0 +1,16 @@ +{ + "variants": { + "axis=x": { + "model": "wild_wind_wilderness:block/blaze_wood", + "x": 90, + "y": 90 + }, + "axis=y": { + "model": "wild_wind_wilderness:block/blaze_wood" + }, + "axis=z": { + "model": "wild_wind_wilderness:block/blaze_wood", + "x": 90 + } + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/scorched_dirt.json b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/scorched_dirt.json new file mode 100644 index 0000000..ac45a27 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/scorched_dirt.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "wild_wind_wilderness:block/scorched_dirt" + } + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/scorched_grass.json b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/scorched_grass.json new file mode 100644 index 0000000..0e56aff --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/scorched_grass.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "wild_wind_wilderness:block/scorched_grass" + } + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/scorched_grass_block.json b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/scorched_grass_block.json new file mode 100644 index 0000000..c80d1eb --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/scorched_grass_block.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "wild_wind_wilderness:block/scorched_grass_block" + } + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/scorched_twig.json b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/scorched_twig.json new file mode 100644 index 0000000..e1ac045 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/scorched_twig.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "wild_wind_wilderness:block/scorched_twig" + } + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/soul_button.json b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/soul_button.json new file mode 100644 index 0000000..498ab5d --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/soul_button.json @@ -0,0 +1,118 @@ +{ + "variants": { + "face=ceiling,facing=east,powered=false": { + "model": "wild_wind_wilderness:block/soul_button", + "x": 180, + "y": 270 + }, + "face=ceiling,facing=east,powered=true": { + "model": "wild_wind_wilderness:block/soul_button_pressed", + "x": 180, + "y": 270 + }, + "face=ceiling,facing=north,powered=false": { + "model": "wild_wind_wilderness:block/soul_button", + "x": 180, + "y": 180 + }, + "face=ceiling,facing=north,powered=true": { + "model": "wild_wind_wilderness:block/soul_button_pressed", + "x": 180, + "y": 180 + }, + "face=ceiling,facing=south,powered=false": { + "model": "wild_wind_wilderness:block/soul_button", + "x": 180 + }, + "face=ceiling,facing=south,powered=true": { + "model": "wild_wind_wilderness:block/soul_button_pressed", + "x": 180 + }, + "face=ceiling,facing=west,powered=false": { + "model": "wild_wind_wilderness:block/soul_button", + "x": 180, + "y": 90 + }, + "face=ceiling,facing=west,powered=true": { + "model": "wild_wind_wilderness:block/soul_button_pressed", + "x": 180, + "y": 90 + }, + "face=floor,facing=east,powered=false": { + "model": "wild_wind_wilderness:block/soul_button", + "y": 90 + }, + "face=floor,facing=east,powered=true": { + "model": "wild_wind_wilderness:block/soul_button_pressed", + "y": 90 + }, + "face=floor,facing=north,powered=false": { + "model": "wild_wind_wilderness:block/soul_button" + }, + "face=floor,facing=north,powered=true": { + "model": "wild_wind_wilderness:block/soul_button_pressed" + }, + "face=floor,facing=south,powered=false": { + "model": "wild_wind_wilderness:block/soul_button", + "y": 180 + }, + "face=floor,facing=south,powered=true": { + "model": "wild_wind_wilderness:block/soul_button_pressed", + "y": 180 + }, + "face=floor,facing=west,powered=false": { + "model": "wild_wind_wilderness:block/soul_button", + "y": 270 + }, + "face=floor,facing=west,powered=true": { + "model": "wild_wind_wilderness:block/soul_button_pressed", + "y": 270 + }, + "face=wall,facing=east,powered=false": { + "model": "wild_wind_wilderness:block/soul_button", + "uvlock": true, + "x": 90, + "y": 90 + }, + "face=wall,facing=east,powered=true": { + "model": "wild_wind_wilderness:block/soul_button_pressed", + "uvlock": true, + "x": 90, + "y": 90 + }, + "face=wall,facing=north,powered=false": { + "model": "wild_wind_wilderness:block/soul_button", + "uvlock": true, + "x": 90 + }, + "face=wall,facing=north,powered=true": { + "model": "wild_wind_wilderness:block/soul_button_pressed", + "uvlock": true, + "x": 90 + }, + "face=wall,facing=south,powered=false": { + "model": "wild_wind_wilderness:block/soul_button", + "uvlock": true, + "x": 90, + "y": 180 + }, + "face=wall,facing=south,powered=true": { + "model": "wild_wind_wilderness:block/soul_button_pressed", + "uvlock": true, + "x": 90, + "y": 180 + }, + "face=wall,facing=west,powered=false": { + "model": "wild_wind_wilderness:block/soul_button", + "uvlock": true, + "x": 90, + "y": 270 + }, + "face=wall,facing=west,powered=true": { + "model": "wild_wind_wilderness:block/soul_button_pressed", + "uvlock": true, + "x": 90, + "y": 270 + } + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/soul_door.json b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/soul_door.json new file mode 100644 index 0000000..2855a12 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/soul_door.json @@ -0,0 +1,124 @@ +{ + "variants": { + "facing=east,half=lower,hinge=left,open=false": { + "model": "wild_wind_wilderness:block/soul_door_bottom_left" + }, + "facing=east,half=lower,hinge=left,open=true": { + "model": "wild_wind_wilderness:block/soul_door_bottom_left_open", + "y": 90 + }, + "facing=east,half=lower,hinge=right,open=false": { + "model": "wild_wind_wilderness:block/soul_door_bottom_right" + }, + "facing=east,half=lower,hinge=right,open=true": { + "model": "wild_wind_wilderness:block/soul_door_bottom_right_open", + "y": 270 + }, + "facing=east,half=upper,hinge=left,open=false": { + "model": "wild_wind_wilderness:block/soul_door_top_left" + }, + "facing=east,half=upper,hinge=left,open=true": { + "model": "wild_wind_wilderness:block/soul_door_top_left_open", + "y": 90 + }, + "facing=east,half=upper,hinge=right,open=false": { + "model": "wild_wind_wilderness:block/soul_door_top_right" + }, + "facing=east,half=upper,hinge=right,open=true": { + "model": "wild_wind_wilderness:block/soul_door_top_right_open", + "y": 270 + }, + "facing=north,half=lower,hinge=left,open=false": { + "model": "wild_wind_wilderness:block/soul_door_bottom_left", + "y": 270 + }, + "facing=north,half=lower,hinge=left,open=true": { + "model": "wild_wind_wilderness:block/soul_door_bottom_left_open" + }, + "facing=north,half=lower,hinge=right,open=false": { + "model": "wild_wind_wilderness:block/soul_door_bottom_right", + "y": 270 + }, + "facing=north,half=lower,hinge=right,open=true": { + "model": "wild_wind_wilderness:block/soul_door_bottom_right_open", + "y": 180 + }, + "facing=north,half=upper,hinge=left,open=false": { + "model": "wild_wind_wilderness:block/soul_door_top_left", + "y": 270 + }, + "facing=north,half=upper,hinge=left,open=true": { + "model": "wild_wind_wilderness:block/soul_door_top_left_open" + }, + "facing=north,half=upper,hinge=right,open=false": { + "model": "wild_wind_wilderness:block/soul_door_top_right", + "y": 270 + }, + "facing=north,half=upper,hinge=right,open=true": { + "model": "wild_wind_wilderness:block/soul_door_top_right_open", + "y": 180 + }, + "facing=south,half=lower,hinge=left,open=false": { + "model": "wild_wind_wilderness:block/soul_door_bottom_left", + "y": 90 + }, + "facing=south,half=lower,hinge=left,open=true": { + "model": "wild_wind_wilderness:block/soul_door_bottom_left_open", + "y": 180 + }, + "facing=south,half=lower,hinge=right,open=false": { + "model": "wild_wind_wilderness:block/soul_door_bottom_right", + "y": 90 + }, + "facing=south,half=lower,hinge=right,open=true": { + "model": "wild_wind_wilderness:block/soul_door_bottom_right_open" + }, + "facing=south,half=upper,hinge=left,open=false": { + "model": "wild_wind_wilderness:block/soul_door_top_left", + "y": 90 + }, + "facing=south,half=upper,hinge=left,open=true": { + "model": "wild_wind_wilderness:block/soul_door_top_left_open", + "y": 180 + }, + "facing=south,half=upper,hinge=right,open=false": { + "model": "wild_wind_wilderness:block/soul_door_top_right", + "y": 90 + }, + "facing=south,half=upper,hinge=right,open=true": { + "model": "wild_wind_wilderness:block/soul_door_top_right_open" + }, + "facing=west,half=lower,hinge=left,open=false": { + "model": "wild_wind_wilderness:block/soul_door_bottom_left", + "y": 180 + }, + "facing=west,half=lower,hinge=left,open=true": { + "model": "wild_wind_wilderness:block/soul_door_bottom_left_open", + "y": 270 + }, + "facing=west,half=lower,hinge=right,open=false": { + "model": "wild_wind_wilderness:block/soul_door_bottom_right", + "y": 180 + }, + "facing=west,half=lower,hinge=right,open=true": { + "model": "wild_wind_wilderness:block/soul_door_bottom_right_open", + "y": 90 + }, + "facing=west,half=upper,hinge=left,open=false": { + "model": "wild_wind_wilderness:block/soul_door_top_left", + "y": 180 + }, + "facing=west,half=upper,hinge=left,open=true": { + "model": "wild_wind_wilderness:block/soul_door_top_left_open", + "y": 270 + }, + "facing=west,half=upper,hinge=right,open=false": { + "model": "wild_wind_wilderness:block/soul_door_top_right", + "y": 180 + }, + "facing=west,half=upper,hinge=right,open=true": { + "model": "wild_wind_wilderness:block/soul_door_top_right_open", + "y": 90 + } + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/soul_fence.json b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/soul_fence.json new file mode 100644 index 0000000..d986c20 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/soul_fence.json @@ -0,0 +1,48 @@ +{ + "multipart": [ + { + "apply": { + "model": "wild_wind_wilderness:block/soul_fence_post" + } + }, + { + "apply": { + "model": "wild_wind_wilderness:block/soul_fence_side", + "uvlock": true + }, + "when": { + "north": "true" + } + }, + { + "apply": { + "model": "wild_wind_wilderness:block/soul_fence_side", + "uvlock": true, + "y": 90 + }, + "when": { + "east": "true" + } + }, + { + "apply": { + "model": "wild_wind_wilderness:block/soul_fence_side", + "uvlock": true, + "y": 180 + }, + "when": { + "south": "true" + } + }, + { + "apply": { + "model": "wild_wind_wilderness:block/soul_fence_side", + "uvlock": true, + "y": 270 + }, + "when": { + "west": "true" + } + } + ] +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/soul_fence_gate.json b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/soul_fence_gate.json new file mode 100644 index 0000000..44f1e65 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/soul_fence_gate.json @@ -0,0 +1,80 @@ +{ + "variants": { + "facing=east,in_wall=false,open=false": { + "model": "wild_wind_wilderness:block/soul_fence_gate", + "uvlock": true, + "y": 270 + }, + "facing=east,in_wall=false,open=true": { + "model": "wild_wind_wilderness:block/soul_fence_gate_open", + "uvlock": true, + "y": 270 + }, + "facing=east,in_wall=true,open=false": { + "model": "wild_wind_wilderness:block/soul_fence_gate_wall", + "uvlock": true, + "y": 270 + }, + "facing=east,in_wall=true,open=true": { + "model": "wild_wind_wilderness:block/soul_fence_gate_wall_open", + "uvlock": true, + "y": 270 + }, + "facing=north,in_wall=false,open=false": { + "model": "wild_wind_wilderness:block/soul_fence_gate", + "uvlock": true, + "y": 180 + }, + "facing=north,in_wall=false,open=true": { + "model": "wild_wind_wilderness:block/soul_fence_gate_open", + "uvlock": true, + "y": 180 + }, + "facing=north,in_wall=true,open=false": { + "model": "wild_wind_wilderness:block/soul_fence_gate_wall", + "uvlock": true, + "y": 180 + }, + "facing=north,in_wall=true,open=true": { + "model": "wild_wind_wilderness:block/soul_fence_gate_wall_open", + "uvlock": true, + "y": 180 + }, + "facing=south,in_wall=false,open=false": { + "model": "wild_wind_wilderness:block/soul_fence_gate", + "uvlock": true + }, + "facing=south,in_wall=false,open=true": { + "model": "wild_wind_wilderness:block/soul_fence_gate_open", + "uvlock": true + }, + "facing=south,in_wall=true,open=false": { + "model": "wild_wind_wilderness:block/soul_fence_gate_wall", + "uvlock": true + }, + "facing=south,in_wall=true,open=true": { + "model": "wild_wind_wilderness:block/soul_fence_gate_wall_open", + "uvlock": true + }, + "facing=west,in_wall=false,open=false": { + "model": "wild_wind_wilderness:block/soul_fence_gate", + "uvlock": true, + "y": 90 + }, + "facing=west,in_wall=false,open=true": { + "model": "wild_wind_wilderness:block/soul_fence_gate_open", + "uvlock": true, + "y": 90 + }, + "facing=west,in_wall=true,open=false": { + "model": "wild_wind_wilderness:block/soul_fence_gate_wall", + "uvlock": true, + "y": 90 + }, + "facing=west,in_wall=true,open=true": { + "model": "wild_wind_wilderness:block/soul_fence_gate_wall_open", + "uvlock": true, + "y": 90 + } + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/soul_leaves.json b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/soul_leaves.json new file mode 100644 index 0000000..7b4ef47 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/soul_leaves.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "wild_wind_wilderness:block/soul_leaves" + } + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/soul_log.json b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/soul_log.json new file mode 100644 index 0000000..38f0ceb --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/soul_log.json @@ -0,0 +1,16 @@ +{ + "variants": { + "axis=x": { + "model": "wild_wind_wilderness:block/soul_log_horizontal", + "x": 90, + "y": 90 + }, + "axis=y": { + "model": "wild_wind_wilderness:block/soul_log" + }, + "axis=z": { + "model": "wild_wind_wilderness:block/soul_log_horizontal", + "x": 90 + } + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/soul_planks.json b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/soul_planks.json new file mode 100644 index 0000000..9c95c1b --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/soul_planks.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "wild_wind_wilderness:block/soul_planks" + } + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/soul_pressure_plate.json b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/soul_pressure_plate.json new file mode 100644 index 0000000..d1d2320 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/soul_pressure_plate.json @@ -0,0 +1,10 @@ +{ + "variants": { + "powered=false": { + "model": "wild_wind_wilderness:block/soul_pressure_plate" + }, + "powered=true": { + "model": "wild_wind_wilderness:block/soul_pressure_plate_down" + } + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/soul_sapling.json b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/soul_sapling.json new file mode 100644 index 0000000..8ad94d2 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/soul_sapling.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "wild_wind_wilderness:block/soul_sapling" + } + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/soul_slab.json b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/soul_slab.json new file mode 100644 index 0000000..89a0900 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/soul_slab.json @@ -0,0 +1,13 @@ +{ + "variants": { + "type=bottom": { + "model": "wild_wind_wilderness:block/soul_slab" + }, + "type=double": { + "model": "wild_wind_wilderness:block/soul_planks" + }, + "type=top": { + "model": "wild_wind_wilderness:block/soul_slab_top" + } + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/soul_stairs.json b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/soul_stairs.json new file mode 100644 index 0000000..8480d90 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/soul_stairs.json @@ -0,0 +1,209 @@ +{ + "variants": { + "facing=east,half=bottom,shape=inner_left": { + "model": "wild_wind_wilderness:block/soul_stairs_inner", + "uvlock": true, + "y": 270 + }, + "facing=east,half=bottom,shape=inner_right": { + "model": "wild_wind_wilderness:block/soul_stairs_inner" + }, + "facing=east,half=bottom,shape=outer_left": { + "model": "wild_wind_wilderness:block/soul_stairs_outer", + "uvlock": true, + "y": 270 + }, + "facing=east,half=bottom,shape=outer_right": { + "model": "wild_wind_wilderness:block/soul_stairs_outer" + }, + "facing=east,half=bottom,shape=straight": { + "model": "wild_wind_wilderness:block/soul_stairs" + }, + "facing=east,half=top,shape=inner_left": { + "model": "wild_wind_wilderness:block/soul_stairs_inner", + "uvlock": true, + "x": 180 + }, + "facing=east,half=top,shape=inner_right": { + "model": "wild_wind_wilderness:block/soul_stairs_inner", + "uvlock": true, + "x": 180, + "y": 90 + }, + "facing=east,half=top,shape=outer_left": { + "model": "wild_wind_wilderness:block/soul_stairs_outer", + "uvlock": true, + "x": 180 + }, + "facing=east,half=top,shape=outer_right": { + "model": "wild_wind_wilderness:block/soul_stairs_outer", + "uvlock": true, + "x": 180, + "y": 90 + }, + "facing=east,half=top,shape=straight": { + "model": "wild_wind_wilderness:block/soul_stairs", + "uvlock": true, + "x": 180 + }, + "facing=north,half=bottom,shape=inner_left": { + "model": "wild_wind_wilderness:block/soul_stairs_inner", + "uvlock": true, + "y": 180 + }, + "facing=north,half=bottom,shape=inner_right": { + "model": "wild_wind_wilderness:block/soul_stairs_inner", + "uvlock": true, + "y": 270 + }, + "facing=north,half=bottom,shape=outer_left": { + "model": "wild_wind_wilderness:block/soul_stairs_outer", + "uvlock": true, + "y": 180 + }, + "facing=north,half=bottom,shape=outer_right": { + "model": "wild_wind_wilderness:block/soul_stairs_outer", + "uvlock": true, + "y": 270 + }, + "facing=north,half=bottom,shape=straight": { + "model": "wild_wind_wilderness:block/soul_stairs", + "uvlock": true, + "y": 270 + }, + "facing=north,half=top,shape=inner_left": { + "model": "wild_wind_wilderness:block/soul_stairs_inner", + "uvlock": true, + "x": 180, + "y": 270 + }, + "facing=north,half=top,shape=inner_right": { + "model": "wild_wind_wilderness:block/soul_stairs_inner", + "uvlock": true, + "x": 180 + }, + "facing=north,half=top,shape=outer_left": { + "model": "wild_wind_wilderness:block/soul_stairs_outer", + "uvlock": true, + "x": 180, + "y": 270 + }, + "facing=north,half=top,shape=outer_right": { + "model": "wild_wind_wilderness:block/soul_stairs_outer", + "uvlock": true, + "x": 180 + }, + "facing=north,half=top,shape=straight": { + "model": "wild_wind_wilderness:block/soul_stairs", + "uvlock": true, + "x": 180, + "y": 270 + }, + "facing=south,half=bottom,shape=inner_left": { + "model": "wild_wind_wilderness:block/soul_stairs_inner" + }, + "facing=south,half=bottom,shape=inner_right": { + "model": "wild_wind_wilderness:block/soul_stairs_inner", + "uvlock": true, + "y": 90 + }, + "facing=south,half=bottom,shape=outer_left": { + "model": "wild_wind_wilderness:block/soul_stairs_outer" + }, + "facing=south,half=bottom,shape=outer_right": { + "model": "wild_wind_wilderness:block/soul_stairs_outer", + "uvlock": true, + "y": 90 + }, + "facing=south,half=bottom,shape=straight": { + "model": "wild_wind_wilderness:block/soul_stairs", + "uvlock": true, + "y": 90 + }, + "facing=south,half=top,shape=inner_left": { + "model": "wild_wind_wilderness:block/soul_stairs_inner", + "uvlock": true, + "x": 180, + "y": 90 + }, + "facing=south,half=top,shape=inner_right": { + "model": "wild_wind_wilderness:block/soul_stairs_inner", + "uvlock": true, + "x": 180, + "y": 180 + }, + "facing=south,half=top,shape=outer_left": { + "model": "wild_wind_wilderness:block/soul_stairs_outer", + "uvlock": true, + "x": 180, + "y": 90 + }, + "facing=south,half=top,shape=outer_right": { + "model": "wild_wind_wilderness:block/soul_stairs_outer", + "uvlock": true, + "x": 180, + "y": 180 + }, + "facing=south,half=top,shape=straight": { + "model": "wild_wind_wilderness:block/soul_stairs", + "uvlock": true, + "x": 180, + "y": 90 + }, + "facing=west,half=bottom,shape=inner_left": { + "model": "wild_wind_wilderness:block/soul_stairs_inner", + "uvlock": true, + "y": 90 + }, + "facing=west,half=bottom,shape=inner_right": { + "model": "wild_wind_wilderness:block/soul_stairs_inner", + "uvlock": true, + "y": 180 + }, + "facing=west,half=bottom,shape=outer_left": { + "model": "wild_wind_wilderness:block/soul_stairs_outer", + "uvlock": true, + "y": 90 + }, + "facing=west,half=bottom,shape=outer_right": { + "model": "wild_wind_wilderness:block/soul_stairs_outer", + "uvlock": true, + "y": 180 + }, + "facing=west,half=bottom,shape=straight": { + "model": "wild_wind_wilderness:block/soul_stairs", + "uvlock": true, + "y": 180 + }, + "facing=west,half=top,shape=inner_left": { + "model": "wild_wind_wilderness:block/soul_stairs_inner", + "uvlock": true, + "x": 180, + "y": 180 + }, + "facing=west,half=top,shape=inner_right": { + "model": "wild_wind_wilderness:block/soul_stairs_inner", + "uvlock": true, + "x": 180, + "y": 270 + }, + "facing=west,half=top,shape=outer_left": { + "model": "wild_wind_wilderness:block/soul_stairs_outer", + "uvlock": true, + "x": 180, + "y": 180 + }, + "facing=west,half=top,shape=outer_right": { + "model": "wild_wind_wilderness:block/soul_stairs_outer", + "uvlock": true, + "x": 180, + "y": 270 + }, + "facing=west,half=top,shape=straight": { + "model": "wild_wind_wilderness:block/soul_stairs", + "uvlock": true, + "x": 180, + "y": 180 + } + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/soul_trapdoor.json b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/soul_trapdoor.json new file mode 100644 index 0000000..07e831d --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/soul_trapdoor.json @@ -0,0 +1,58 @@ +{ + "variants": { + "facing=east,half=bottom,open=false": { + "model": "wild_wind_wilderness:block/soul_trapdoor_bottom" + }, + "facing=east,half=bottom,open=true": { + "model": "wild_wind_wilderness:block/soul_trapdoor_open", + "y": 90 + }, + "facing=east,half=top,open=false": { + "model": "wild_wind_wilderness:block/soul_trapdoor_top" + }, + "facing=east,half=top,open=true": { + "model": "wild_wind_wilderness:block/soul_trapdoor_open", + "y": 90 + }, + "facing=north,half=bottom,open=false": { + "model": "wild_wind_wilderness:block/soul_trapdoor_bottom" + }, + "facing=north,half=bottom,open=true": { + "model": "wild_wind_wilderness:block/soul_trapdoor_open" + }, + "facing=north,half=top,open=false": { + "model": "wild_wind_wilderness:block/soul_trapdoor_top" + }, + "facing=north,half=top,open=true": { + "model": "wild_wind_wilderness:block/soul_trapdoor_open" + }, + "facing=south,half=bottom,open=false": { + "model": "wild_wind_wilderness:block/soul_trapdoor_bottom" + }, + "facing=south,half=bottom,open=true": { + "model": "wild_wind_wilderness:block/soul_trapdoor_open", + "y": 180 + }, + "facing=south,half=top,open=false": { + "model": "wild_wind_wilderness:block/soul_trapdoor_top" + }, + "facing=south,half=top,open=true": { + "model": "wild_wind_wilderness:block/soul_trapdoor_open", + "y": 180 + }, + "facing=west,half=bottom,open=false": { + "model": "wild_wind_wilderness:block/soul_trapdoor_bottom" + }, + "facing=west,half=bottom,open=true": { + "model": "wild_wind_wilderness:block/soul_trapdoor_open", + "y": 270 + }, + "facing=west,half=top,open=false": { + "model": "wild_wind_wilderness:block/soul_trapdoor_top" + }, + "facing=west,half=top,open=true": { + "model": "wild_wind_wilderness:block/soul_trapdoor_open", + "y": 270 + } + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/soul_wood.json b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/soul_wood.json new file mode 100644 index 0000000..f12f569 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/soul_wood.json @@ -0,0 +1,16 @@ +{ + "variants": { + "axis=x": { + "model": "wild_wind_wilderness:block/soul_wood", + "x": 90, + "y": 90 + }, + "axis=y": { + "model": "wild_wind_wilderness:block/soul_wood" + }, + "axis=z": { + "model": "wild_wind_wilderness:block/soul_wood", + "x": 90 + } + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/stripped_blaze_log.json b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/stripped_blaze_log.json new file mode 100644 index 0000000..e41cc6f --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/stripped_blaze_log.json @@ -0,0 +1,16 @@ +{ + "variants": { + "axis=x": { + "model": "wild_wind_wilderness:block/stripped_blaze_log_horizontal", + "x": 90, + "y": 90 + }, + "axis=y": { + "model": "wild_wind_wilderness:block/stripped_blaze_log" + }, + "axis=z": { + "model": "wild_wind_wilderness:block/stripped_blaze_log_horizontal", + "x": 90 + } + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/stripped_blaze_wood.json b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/stripped_blaze_wood.json new file mode 100644 index 0000000..995d07c --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/stripped_blaze_wood.json @@ -0,0 +1,16 @@ +{ + "variants": { + "axis=x": { + "model": "wild_wind_wilderness:block/stripped_blaze_wood", + "x": 90, + "y": 90 + }, + "axis=y": { + "model": "wild_wind_wilderness:block/stripped_blaze_wood" + }, + "axis=z": { + "model": "wild_wind_wilderness:block/stripped_blaze_wood", + "x": 90 + } + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/stripped_soul_log.json b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/stripped_soul_log.json new file mode 100644 index 0000000..adffdd3 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/stripped_soul_log.json @@ -0,0 +1,16 @@ +{ + "variants": { + "axis=x": { + "model": "wild_wind_wilderness:block/stripped_soul_log_horizontal", + "x": 90, + "y": 90 + }, + "axis=y": { + "model": "wild_wind_wilderness:block/stripped_soul_log" + }, + "axis=z": { + "model": "wild_wind_wilderness:block/stripped_soul_log_horizontal", + "x": 90 + } + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/stripped_soul_wood.json b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/stripped_soul_wood.json new file mode 100644 index 0000000..493f993 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/blockstates/stripped_soul_wood.json @@ -0,0 +1,16 @@ +{ + "variants": { + "axis=x": { + "model": "wild_wind_wilderness:block/stripped_soul_wood", + "x": 90, + "y": 90 + }, + "axis=y": { + "model": "wild_wind_wilderness:block/stripped_soul_wood" + }, + "axis=z": { + "model": "wild_wind_wilderness:block/stripped_soul_wood", + "x": 90 + } + } +} diff --git a/src/hfas/resources/assets/ww_hfas/geckolib/animations/entity/mudcrab.animation.json b/src/wilderness/resources/assets/wild_wind_wilderness/geckolib/animations/entity/mudcrab.animation.json similarity index 100% rename from src/hfas/resources/assets/ww_hfas/geckolib/animations/entity/mudcrab.animation.json rename to src/wilderness/resources/assets/wild_wind_wilderness/geckolib/animations/entity/mudcrab.animation.json diff --git a/src/hfas/resources/assets/ww_hfas/geckolib/animations/entity/piranha.animation.json b/src/wilderness/resources/assets/wild_wind_wilderness/geckolib/animations/entity/piranha.animation.json similarity index 100% rename from src/hfas/resources/assets/ww_hfas/geckolib/animations/entity/piranha.animation.json rename to src/wilderness/resources/assets/wild_wind_wilderness/geckolib/animations/entity/piranha.animation.json diff --git a/src/hfas/resources/assets/ww_hfas/geckolib/models/entity/mudcrab.geo.json b/src/wilderness/resources/assets/wild_wind_wilderness/geckolib/models/entity/mudcrab.geo.json similarity index 100% rename from src/hfas/resources/assets/ww_hfas/geckolib/models/entity/mudcrab.geo.json rename to src/wilderness/resources/assets/wild_wind_wilderness/geckolib/models/entity/mudcrab.geo.json diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/geckolib/models/entity/piranha.geo.json b/src/wilderness/resources/assets/wild_wind_wilderness/geckolib/models/entity/piranha.geo.json new file mode 100644 index 0000000..a562bad --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/geckolib/models/entity/piranha.geo.json @@ -0,0 +1,175 @@ +{ + "format_version": "1.12.0", + "minecraft:geometry": [ + { + "description": { + "identifier": "geometry.unknown", + "texture_width": 32, + "texture_height": 32, + "visible_bounds_width": 2, + "visible_bounds_height": 1.5, + "visible_bounds_offset": [0, 0.25, 0] + }, + "bones": [ + { + "name": "root", + "pivot": [0, 3, 0] + }, + { + "name": "bone", + "parent": "root", + "pivot": [-0.25, 3, -1], + "cubes": [ + { + "origin": [-1, 2, -4], + "size": [2, 4, 3], + "uv": { + "north": {"uv": [6, 18], "uv_size": [2, 4]}, + "east": {"uv": [4, 0], "uv_size": [3, 4]}, + "south": {"uv": [18, 6], "uv_size": [2, 4]}, + "west": {"uv": [0, 5], "uv_size": [3, 4]}, + "up": {"uv": [0, 14], "uv_size": [2, 3]}, + "down": {"uv": [3, 17], "uv_size": [2, -3]} + } + }, + { + "origin": [-1, 0, -2], + "size": [2, 2, 1], + "uv": { + "north": {"uv": [12, 18], "uv_size": [2, 2]}, + "east": {"uv": [20, 14], "uv_size": [1, 2]}, + "south": {"uv": [20, 0], "uv_size": [2, 2]}, + "west": {"uv": [16, 17], "uv_size": [1, 2]}, + "up": {"uv": [0, 22], "uv_size": [2, 1]}, + "down": {"uv": [3, 23], "uv_size": [2, -1]} + } + }, + { + "origin": [-0.75, 1, -3.5], + "size": [0, 1, 1], + "uv": { + "east": {"uv": [0, 24], "uv_size": [1, 1]} + } + }, + { + "origin": [0.75, 1, -3.5], + "size": [0, 1, 1], + "uv": { + "west": {"uv": [1, 24], "uv_size": [-1, 1]} + } + } + ] + }, + { + "name": "mouth", + "parent": "bone", + "pivot": [0, 1.5, -2], + "cubes": [ + { + "origin": [-0.5, 0, -4], + "size": [1, 2, 2], + "uv": { + "north": {"uv": [6, 10], "uv_size": [1, 2]}, + "east": {"uv": [9, 18], "uv_size": [2, 2]}, + "south": {"uv": [20, 3], "uv_size": [1, 2]}, + "west": {"uv": [18, 11], "uv_size": [2, 2]}, + "up": {"uv": [15, 20], "uv_size": [1, 2]}, + "down": {"uv": [17, 22], "uv_size": [1, -2]} + } + } + ] + }, + { + "name": "bone2", + "parent": "root", + "pivot": [0, 3, -1], + "cubes": [ + { + "origin": [0, 6, -2], + "size": [0, 2, 6], + "uv": { + "north": {"uv": [10, 21], "uv_size": [0, 2]}, + "east": {"uv": [13, 0], "uv_size": [6, 2]}, + "south": {"uv": [11, 21], "uv_size": [0, 2]}, + "west": {"uv": [13, 3], "uv_size": [6, 2]}, + "up": {"uv": [12, 21], "uv_size": [0, 6]}, + "down": {"uv": [13, 27], "uv_size": [0, -6]} + } + }, + { + "origin": [-1, 2, -1], + "size": [2, 4, 4], + "uv": { + "north": {"uv": [6, 18], "uv_size": [2, 4]}, + "east": {"uv": [0, 0], "uv_size": [4, 4]}, + "south": {"uv": [18, 6], "uv_size": [2, 4]}, + "west": {"uv": [3, 5], "uv_size": [4, 4]}, + "up": {"uv": [0, 10], "uv_size": [2, 4]}, + "down": {"uv": [3, 14], "uv_size": [2, -4]} + } + }, + { + "origin": [-1, 0, -1], + "size": [0, 3, 4], + "pivot": [-1, 2, -1], + "rotation": [0, -15, 0], + "uv": { + "north": {"uv": [22, 13], "uv_size": [0, 3]}, + "east": {"uv": [6, 14], "uv_size": [4, 3]}, + "south": {"uv": [22, 17], "uv_size": [0, 3]}, + "west": {"uv": [11, 14], "uv_size": [4, 3]}, + "up": {"uv": [22, 21], "uv_size": [0, 4]}, + "down": {"uv": [23, 4], "uv_size": [0, -4]} + } + }, + { + "origin": [-1, 0, -1], + "size": [2, 2, 4], + "uv": { + "north": {"uv": [12, 18], "uv_size": [2, 2]}, + "east": {"uv": [16, 14], "uv_size": [4, 2]}, + "south": {"uv": [20, 0], "uv_size": [2, 2]}, + "west": {"uv": [17, 17], "uv_size": [4, 2]}, + "up": {"uv": [0, 18], "uv_size": [2, 4]}, + "down": {"uv": [3, 22], "uv_size": [2, -4]} + } + }, + { + "origin": [1, 0, -1], + "size": [0, 3, 4], + "pivot": [1, 2, -1], + "rotation": [0, 15, 0], + "uv": { + "north": {"uv": [14, 21], "uv_size": [0, 3]}, + "east": {"uv": [13, 6], "uv_size": [4, 3]}, + "south": {"uv": [21, 20], "uv_size": [0, 3]}, + "west": {"uv": [13, 10], "uv_size": [4, 3]}, + "up": {"uv": [22, 3], "uv_size": [0, 4]}, + "down": {"uv": [22, 12], "uv_size": [0, -4]} + } + } + ] + }, + { + "name": "tail", + "parent": "bone2", + "pivot": [0, 3, 3], + "cubes": [ + { + "origin": [0, 0, 3], + "size": [0, 6, 4], + "uv": { + "north": {"uv": [19, 20], "uv_size": [0, 6]}, + "east": {"uv": [8, 0], "uv_size": [4, 6]}, + "south": {"uv": [20, 20], "uv_size": [0, 6]}, + "west": {"uv": [8, 7], "uv_size": [4, 6]}, + "up": {"uv": [21, 6], "uv_size": [0, 4]}, + "down": {"uv": [9, 25], "uv_size": [0, -4]} + } + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_boat.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_boat.json new file mode 100644 index 0000000..dd165d5 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_boat.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:item/blaze_boat" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_button.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_button.json new file mode 100644 index 0000000..89e58ca --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_button.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:block/blaze_button_inventory" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_chest_boat.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_chest_boat.json new file mode 100644 index 0000000..357c1f8 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_chest_boat.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:item/blaze_chest_boat" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_door.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_door.json new file mode 100644 index 0000000..d8506a5 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_door.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:item/blaze_door" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_fence.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_fence.json new file mode 100644 index 0000000..8208f87 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_fence.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:block/blaze_fence_inventory" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_fence_gate.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_fence_gate.json new file mode 100644 index 0000000..2d10aca --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_fence_gate.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:block/blaze_fence_gate" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_hanging_sign.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_hanging_sign.json new file mode 100644 index 0000000..f96455e --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_hanging_sign.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:item/blaze_hanging_sign" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_leaves.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_leaves.json new file mode 100644 index 0000000..0f3e79a --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_leaves.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:block/blaze_leaves" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_log.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_log.json new file mode 100644 index 0000000..42eb1ae --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_log.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:block/blaze_log" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_planks.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_planks.json new file mode 100644 index 0000000..a161d91 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_planks.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:block/blaze_planks" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_pressure_plate.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_pressure_plate.json new file mode 100644 index 0000000..c84e33d --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_pressure_plate.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:block/blaze_pressure_plate" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_sapling.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_sapling.json new file mode 100644 index 0000000..1f6501e --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_sapling.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:block/blaze_sapling" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_sign.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_sign.json new file mode 100644 index 0000000..083b62d --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_sign.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:item/blaze_sign" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_slab.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_slab.json new file mode 100644 index 0000000..572a143 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_slab.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:block/blaze_slab" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_stairs.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_stairs.json new file mode 100644 index 0000000..747d24d --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_stairs.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:block/blaze_stairs" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_trapdoor.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_trapdoor.json new file mode 100644 index 0000000..97d74e0 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_trapdoor.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:block/blaze_trapdoor_bottom" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_wood.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_wood.json new file mode 100644 index 0000000..ecd8694 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/blaze_wood.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:block/blaze_wood" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/cooked_piranha.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/cooked_piranha.json new file mode 100644 index 0000000..6879b73 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/cooked_piranha.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:item/cooked_piranha" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/crab_claw.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/crab_claw.json new file mode 100644 index 0000000..2a27edb --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/crab_claw.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:item/crab_claw" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/fang.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/fang.json new file mode 100644 index 0000000..22b32cf --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/fang.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:item/fang" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/mudcrab_bucket.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/mudcrab_bucket.json new file mode 100644 index 0000000..98e3e08 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/mudcrab_bucket.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:item/mudcrab_bucket" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/mudcrab_spawn_egg.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/mudcrab_spawn_egg.json new file mode 100644 index 0000000..a79c2fd --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/mudcrab_spawn_egg.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:item/mudcrab_spawn_egg" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/muddy_pig_spawn_egg.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/muddy_pig_spawn_egg.json new file mode 100644 index 0000000..b7869a9 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/muddy_pig_spawn_egg.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "minecraft:item/pig_spawn_egg" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/omni_claw.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/omni_claw.json new file mode 100644 index 0000000..7e0d87f --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/omni_claw.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:item/omni_claw" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/piranha.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/piranha.json new file mode 100644 index 0000000..f3487f0 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/piranha.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:item/piranha" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/piranha_bucket.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/piranha_bucket.json new file mode 100644 index 0000000..9a4bbe8 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/piranha_bucket.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:item/piranha_bucket" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/piranha_spawn_egg.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/piranha_spawn_egg.json new file mode 100644 index 0000000..f1fb643 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/piranha_spawn_egg.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:item/piranha_spawn_egg" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/scorched_dirt.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/scorched_dirt.json new file mode 100644 index 0000000..304d21e --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/scorched_dirt.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:block/scorched_dirt" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/scorched_grass.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/scorched_grass.json new file mode 100644 index 0000000..ef7780c --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/scorched_grass.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:block/scorched_grass" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/scorched_grass_block.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/scorched_grass_block.json new file mode 100644 index 0000000..f28cd7d --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/scorched_grass_block.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:block/scorched_grass_block" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/scorched_twig.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/scorched_twig.json new file mode 100644 index 0000000..209308f --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/scorched_twig.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:block/scorched_twig" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_boat.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_boat.json new file mode 100644 index 0000000..014da84 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_boat.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:item/soul_boat" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_button.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_button.json new file mode 100644 index 0000000..36216a5 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_button.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:block/soul_button_inventory" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_chest_boat.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_chest_boat.json new file mode 100644 index 0000000..755768e --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_chest_boat.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:item/soul_chest_boat" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_door.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_door.json new file mode 100644 index 0000000..728ace6 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_door.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:item/soul_door" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_fence.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_fence.json new file mode 100644 index 0000000..bc1bf79 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_fence.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:block/soul_fence_inventory" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_fence_gate.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_fence_gate.json new file mode 100644 index 0000000..d375f4e --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_fence_gate.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:block/soul_fence_gate" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_hanging_sign.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_hanging_sign.json new file mode 100644 index 0000000..9935c50 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_hanging_sign.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:item/soul_hanging_sign" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_leaves.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_leaves.json new file mode 100644 index 0000000..3bb275a --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_leaves.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:block/soul_leaves" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_log.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_log.json new file mode 100644 index 0000000..a0e81d0 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_log.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:block/soul_log" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_planks.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_planks.json new file mode 100644 index 0000000..80a7727 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_planks.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:block/soul_planks" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_pressure_plate.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_pressure_plate.json new file mode 100644 index 0000000..73e1ec7 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_pressure_plate.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:block/soul_pressure_plate" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_sapling.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_sapling.json new file mode 100644 index 0000000..2c52caf --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_sapling.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:block/soul_sapling" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_sign.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_sign.json new file mode 100644 index 0000000..a26e551 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_sign.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:item/soul_sign" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_slab.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_slab.json new file mode 100644 index 0000000..c2057e4 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_slab.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:block/soul_slab" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_stairs.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_stairs.json new file mode 100644 index 0000000..77ccbfe --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_stairs.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:block/soul_stairs" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_trapdoor.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_trapdoor.json new file mode 100644 index 0000000..124b065 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_trapdoor.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:block/soul_trapdoor_bottom" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_wood.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_wood.json new file mode 100644 index 0000000..1996242 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/soul_wood.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:block/soul_wood" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/stripped_blaze_log.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/stripped_blaze_log.json new file mode 100644 index 0000000..e6ae115 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/stripped_blaze_log.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:block/stripped_blaze_log" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/stripped_blaze_wood.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/stripped_blaze_wood.json new file mode 100644 index 0000000..063c923 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/stripped_blaze_wood.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:block/stripped_blaze_wood" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/stripped_soul_log.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/stripped_soul_log.json new file mode 100644 index 0000000..2da8301 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/stripped_soul_log.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:block/stripped_soul_log" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/stripped_soul_wood.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/stripped_soul_wood.json new file mode 100644 index 0000000..24475c1 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/stripped_soul_wood.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "wild_wind_wilderness:block/stripped_soul_wood" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/items/tipped_arrow.json b/src/wilderness/resources/assets/wild_wind_wilderness/items/tipped_arrow.json new file mode 100644 index 0000000..21d3dc2 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/items/tipped_arrow.json @@ -0,0 +1,12 @@ +{ + "model": { + "type": "minecraft:model", + "model": "minecraft:item/tipped_arrow", + "tints": [ + { + "type": "minecraft:potion", + "default": -13083194 + } + ] + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/lang/en_us.json b/src/wilderness/resources/assets/wild_wind_wilderness/lang/en_us.json new file mode 100644 index 0000000..03a0169 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/lang/en_us.json @@ -0,0 +1,68 @@ +{ + "attributes.wild_wind_wilderness.extra_item_pickup_range": "Extra Item Pickup Range", + "block.wild_wind_wilderness.blaze_button": "Blaze Button", + "block.wild_wind_wilderness.blaze_door": "Blaze Door", + "block.wild_wind_wilderness.blaze_fence": "Blaze Fence", + "block.wild_wind_wilderness.blaze_fence_gate": "Blaze Fence Gate", + "block.wild_wind_wilderness.blaze_leaves": "Blaze Leaves", + "block.wild_wind_wilderness.blaze_log": "Blaze Log", + "block.wild_wind_wilderness.blaze_planks": "Blaze Planks", + "block.wild_wind_wilderness.blaze_pressure_plate": "Blaze Pressure Plate", + "block.wild_wind_wilderness.blaze_sapling": "Blaze Sapling", + "block.wild_wind_wilderness.blaze_slab": "Blaze Slab", + "block.wild_wind_wilderness.blaze_stairs": "Blaze Stairs", + "block.wild_wind_wilderness.blaze_trapdoor": "Blaze Trapdoor", + "block.wild_wind_wilderness.blaze_wood": "Blaze Wood", + "block.wild_wind_wilderness.scorched_dirt": "Scorched Dirt", + "block.wild_wind_wilderness.scorched_grass": "Scorched Grass", + "block.wild_wind_wilderness.scorched_grass_block": "Scorched Grass Block", + "block.wild_wind_wilderness.scorched_twig": "Scorched Twig", + "block.wild_wind_wilderness.soul_button": "Soul Button", + "block.wild_wind_wilderness.soul_door": "Soul Door", + "block.wild_wind_wilderness.soul_fence": "Soul Fence", + "block.wild_wind_wilderness.soul_fence_gate": "Soul Fence Gate", + "block.wild_wind_wilderness.soul_leaves": "Soul Leaves", + "block.wild_wind_wilderness.soul_log": "Soul Log", + "block.wild_wind_wilderness.soul_planks": "Soul Planks", + "block.wild_wind_wilderness.soul_pressure_plate": "Soul Pressure Plate", + "block.wild_wind_wilderness.soul_sapling": "Soul Sapling", + "block.wild_wind_wilderness.soul_slab": "Soul Slab", + "block.wild_wind_wilderness.soul_stairs": "Soul Stairs", + "block.wild_wind_wilderness.soul_trapdoor": "Soul Trapdoor", + "block.wild_wind_wilderness.soul_wood": "Soul Wood", + "block.wild_wind_wilderness.stripped_blaze_log": "Stripped Blaze Log", + "block.wild_wind_wilderness.stripped_blaze_wood": "Stripped Blaze Wood", + "block.wild_wind_wilderness.stripped_soul_log": "Stripped Soul Log", + "block.wild_wind_wilderness.stripped_soul_wood": "Stripped Soul Wood", + "effect.wild_wind_wilderness.choke": "Choke", + "effect.wild_wind_wilderness.reach": "Reach", + "effect.wild_wind_wilderness.sink": "Sink", + "entity.wild_wind_wilderness.mudcrab": "Mudcrab", + "entity.wild_wind_wilderness.muddy_pig": "Muddy Pig", + "entity.wild_wind_wilderness.piranha": "Direfish", + "item.minecraft.lingering_potion.effect.long_reach": "Lingering Potion of Reach", + "item.minecraft.lingering_potion.effect.reach": "Lingering Potion of Reach", + "item.minecraft.potion.effect.long_reach": "Potion of Reach", + "item.minecraft.potion.effect.reach": "Potion of Reach", + "item.minecraft.splash_potion.effect.long_reach": "Splash Potion of Reach", + "item.minecraft.splash_potion.effect.reach": "Splash Potion of Reach", + "item.minecraft.tipped_arrow.effect.long_reach": "Arrow of Reach", + "item.minecraft.tipped_arrow.effect.reach": "Arrow of Reach", + "item.wild_wind_wilderness.cooked_piranha": "Cooked Direfish", + "item.wild_wind_wilderness.crab_claw": "Crab Claw", + "item.wild_wind_wilderness.fang": "Fang", + "item.wild_wind_wilderness.mudcrab_bucket": "Bucket of Mudcrab", + "item.wild_wind_wilderness.mudcrab_spawn_egg": "Mudcrab Spawn Egg", + "item.wild_wind_wilderness.muddy_pig_spawn_egg": "Muddy Pig Spawn Egg", + "item.wild_wind_wilderness.omni_claw": "Omni Craw", + "item.wild_wind_wilderness.piranha": "Raw Direfish", + "item.wild_wind_wilderness.piranha_bucket": "Bucket of Direfish", + "item.wild_wind_wilderness.piranha_spawn_egg": "Direfish Spawn Egg", + "item.wild_wind_wilderness.tipped_arrow": "Arrow of Reach", + "item.wild_wind_wilderness.tipped_arrow.effect.long_reach": "Arrow of Reach", + "item.wild_wind_wilderness.tipped_arrow.effect.reach": "Arrow of Reach", + "subtitles.entity.piranha.attack": "Direfish attacks", + "subtitles.entity.piranha.death": "Direfish dies", + "mod.wild_wind.wilderness": "Wild Wind:Wilderness Update", + "entity.wild_wind_wilderness.arrow": "Arrow of Reach" +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/lang/zh_cn.json b/src/wilderness/resources/assets/wild_wind_wilderness/lang/zh_cn.json new file mode 100644 index 0000000..f0adb0d --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/lang/zh_cn.json @@ -0,0 +1,68 @@ +{ + "attributes.wild_wind_wilderness.extra_item_pickup_range": "额外物品拾取距离", + "block.wild_wind_wilderness.blaze_button": "焚烬木按钮", + "block.wild_wind_wilderness.blaze_door": "焚烬木门", + "block.wild_wind_wilderness.blaze_fence": "焚烬木栅栏", + "block.wild_wind_wilderness.blaze_fence_gate": "焚烬木栅栏门", + "block.wild_wind_wilderness.blaze_leaves": "焚烬木树叶", + "block.wild_wind_wilderness.blaze_log": "焚烬木原木", + "block.wild_wind_wilderness.blaze_planks": "焚烬木木板", + "block.wild_wind_wilderness.blaze_pressure_plate": "焚烬木压力板", + "block.wild_wind_wilderness.blaze_sapling": "焚烬木树苗", + "block.wild_wind_wilderness.blaze_slab": "焚烬木台阶", + "block.wild_wind_wilderness.blaze_stairs": "焚烬木楼梯", + "block.wild_wind_wilderness.blaze_trapdoor": "焚烬木活板门", + "block.wild_wind_wilderness.blaze_wood": "焚烬木", + "block.wild_wind_wilderness.scorched_dirt": "焦土", + "block.wild_wind_wilderness.scorched_grass": "焦灰草丛", + "block.wild_wind_wilderness.scorched_grass_block": "焦灰草方块", + "block.wild_wind_wilderness.scorched_twig": "焦灰枝条", + "block.wild_wind_wilderness.soul_button": "灵焰木按钮", + "block.wild_wind_wilderness.soul_door": "灵焰木门", + "block.wild_wind_wilderness.soul_fence": "灵焰木栅栏", + "block.wild_wind_wilderness.soul_fence_gate": "灵焰木栅栏门", + "block.wild_wind_wilderness.soul_leaves": "灵焰木树叶", + "block.wild_wind_wilderness.soul_log": "灵焰木原木", + "block.wild_wind_wilderness.soul_planks": "灵焰木木板", + "block.wild_wind_wilderness.soul_pressure_plate": "灵焰木压力板", + "block.wild_wind_wilderness.soul_sapling": "灵焰木树苗", + "block.wild_wind_wilderness.soul_slab": "灵焰木台阶", + "block.wild_wind_wilderness.soul_stairs": "灵焰木楼梯", + "block.wild_wind_wilderness.soul_trapdoor": "灵焰木活板门", + "block.wild_wind_wilderness.soul_wood": "灵焰木", + "block.wild_wind_wilderness.stripped_blaze_log": "去皮焚烬木原木", + "block.wild_wind_wilderness.stripped_blaze_wood": "去皮焚烬木", + "block.wild_wind_wilderness.stripped_soul_log": "去皮灵焰木原木", + "block.wild_wind_wilderness.stripped_soul_wood": "去皮灵焰木", + "effect.wild_wind_wilderness.choke": "窒息", + "effect.wild_wind_wilderness.reach": "延展", + "effect.wild_wind_wilderness.sink": "沉溺", + "entity.wild_wind_wilderness.mudcrab": "泥沼蟹", + "entity.wild_wind_wilderness.muddy_pig": "泥猪", + "entity.wild_wind_wilderness.piranha": "恐鱼", + "item.minecraft.lingering_potion.effect.long_reach": "滞留型延展药水", + "item.minecraft.lingering_potion.effect.reach": "滞留型延展药水", + "item.minecraft.potion.effect.long_reach": "延展药水", + "item.minecraft.potion.effect.reach": "延展药水", + "item.minecraft.splash_potion.effect.long_reach": "喷溅型延展药水", + "item.minecraft.splash_potion.effect.reach": "喷溅型延展药水", + "item.minecraft.tipped_arrow.effect.long_reach": "延展之箭", + "item.minecraft.tipped_arrow.effect.reach": "延展之箭", + "item.wild_wind_wilderness.cooked_piranha": "熟恐鱼", + "item.wild_wind_wilderness.crab_claw": "蟹钳", + "item.wild_wind_wilderness.fang": "尖牙", + "item.wild_wind_wilderness.mudcrab_bucket": "泥沼蟹桶", + "item.wild_wind_wilderness.mudcrab_spawn_egg": "泥沼蟹刷怪蛋", + "item.wild_wind_wilderness.muddy_pig_spawn_egg": "泥猪刷怪蛋", + "item.wild_wind_wilderness.omni_claw": "万用蟹钳", + "item.wild_wind_wilderness.piranha": "生恐鱼", + "item.wild_wind_wilderness.piranha_bucket": "恐鱼桶", + "item.wild_wind_wilderness.piranha_spawn_egg": "恐鱼刷怪蛋", + "item.wild_wind_wilderness.tipped_arrow": "延展之箭", + "item.wild_wind_wilderness.tipped_arrow.effect.long_reach": "延展之箭", + "item.wild_wind_wilderness.tipped_arrow.effect.reach": "延展之箭", + "subtitles.entity.piranha.attack": "恐鱼袭击", + "subtitles.entity.piranha.death": "恐鱼死亡", + "mod.wild_wind.wilderness": "原野之风:荒野更新", + "entity.wild_wind_wilderness.arrow": "延展之箭" +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_button.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_button.json new file mode 100644 index 0000000..93209a9 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_button.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/button", + "textures": { + "texture": "wild_wind_wilderness:block/blaze_planks" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_button_inventory.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_button_inventory.json new file mode 100644 index 0000000..3e0ed77 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_button_inventory.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/button_inventory", + "textures": { + "texture": "wild_wind_wilderness:block/blaze_planks" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_button_pressed.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_button_pressed.json new file mode 100644 index 0000000..8926d1c --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_button_pressed.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/button_pressed", + "textures": { + "texture": "wild_wind_wilderness:block/blaze_planks" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_door_bottom_left.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_door_bottom_left.json new file mode 100644 index 0000000..7ac0360 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_door_bottom_left.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/door_bottom_left", + "textures": { + "bottom": "wild_wind_wilderness:block/blaze_door_bottom", + "top": "wild_wind_wilderness:block/blaze_door_top" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_door_bottom_left_open.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_door_bottom_left_open.json new file mode 100644 index 0000000..2c797ce --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_door_bottom_left_open.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/door_bottom_left_open", + "textures": { + "bottom": "wild_wind_wilderness:block/blaze_door_bottom", + "top": "wild_wind_wilderness:block/blaze_door_top" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_door_bottom_right.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_door_bottom_right.json new file mode 100644 index 0000000..ba29cfd --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_door_bottom_right.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/door_bottom_right", + "textures": { + "bottom": "wild_wind_wilderness:block/blaze_door_bottom", + "top": "wild_wind_wilderness:block/blaze_door_top" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_door_bottom_right_open.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_door_bottom_right_open.json new file mode 100644 index 0000000..6eef3d3 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_door_bottom_right_open.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/door_bottom_right_open", + "textures": { + "bottom": "wild_wind_wilderness:block/blaze_door_bottom", + "top": "wild_wind_wilderness:block/blaze_door_top" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_door_top_left.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_door_top_left.json new file mode 100644 index 0000000..4b4150f --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_door_top_left.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/door_top_left", + "textures": { + "bottom": "wild_wind_wilderness:block/blaze_door_bottom", + "top": "wild_wind_wilderness:block/blaze_door_top" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_door_top_left_open.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_door_top_left_open.json new file mode 100644 index 0000000..013812b --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_door_top_left_open.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/door_top_left_open", + "textures": { + "bottom": "wild_wind_wilderness:block/blaze_door_bottom", + "top": "wild_wind_wilderness:block/blaze_door_top" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_door_top_right.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_door_top_right.json new file mode 100644 index 0000000..74fa0e0 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_door_top_right.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/door_top_right", + "textures": { + "bottom": "wild_wind_wilderness:block/blaze_door_bottom", + "top": "wild_wind_wilderness:block/blaze_door_top" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_door_top_right_open.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_door_top_right_open.json new file mode 100644 index 0000000..5c59445 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_door_top_right_open.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/door_top_right_open", + "textures": { + "bottom": "wild_wind_wilderness:block/blaze_door_bottom", + "top": "wild_wind_wilderness:block/blaze_door_top" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_fence_gate.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_fence_gate.json new file mode 100644 index 0000000..64d3f9b --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_fence_gate.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/template_fence_gate", + "textures": { + "texture": "wild_wind_wilderness:block/blaze_planks" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_fence_gate_open.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_fence_gate_open.json new file mode 100644 index 0000000..29276cc --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_fence_gate_open.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/template_fence_gate_open", + "textures": { + "texture": "wild_wind_wilderness:block/blaze_planks" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_fence_gate_wall.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_fence_gate_wall.json new file mode 100644 index 0000000..c30a57f --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_fence_gate_wall.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/template_fence_gate_wall", + "textures": { + "texture": "wild_wind_wilderness:block/blaze_planks" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_fence_gate_wall_open.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_fence_gate_wall_open.json new file mode 100644 index 0000000..27c29b5 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_fence_gate_wall_open.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/template_fence_gate_wall_open", + "textures": { + "texture": "wild_wind_wilderness:block/blaze_planks" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_fence_inventory.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_fence_inventory.json new file mode 100644 index 0000000..bf0d822 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_fence_inventory.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/fence_inventory", + "textures": { + "texture": "wild_wind_wilderness:block/blaze_planks" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_fence_post.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_fence_post.json new file mode 100644 index 0000000..02d4a09 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_fence_post.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/fence_post", + "textures": { + "texture": "wild_wind_wilderness:block/blaze_planks" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_fence_side.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_fence_side.json new file mode 100644 index 0000000..1f4c527 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_fence_side.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/fence_side", + "textures": { + "texture": "wild_wind_wilderness:block/blaze_planks" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_hanging_sign_attached_rot_0.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_hanging_sign_attached_rot_0.json new file mode 100644 index 0000000..5f5bfb8 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_hanging_sign_attached_rot_0.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_attached_hanging_sign_rot_0", + "textures": { + "all": "wild_wind_wilderness:block/blaze_hanging_sign", + "particle": "wild_wind_wilderness:block/stripped_blaze_log" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_hanging_sign_attached_rot_1.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_hanging_sign_attached_rot_1.json new file mode 100644 index 0000000..749448e --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_hanging_sign_attached_rot_1.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_attached_hanging_sign_rot_1", + "textures": { + "all": "wild_wind_wilderness:block/blaze_hanging_sign", + "particle": "wild_wind_wilderness:block/stripped_blaze_log" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_hanging_sign_attached_rot_2.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_hanging_sign_attached_rot_2.json new file mode 100644 index 0000000..dc68320 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_hanging_sign_attached_rot_2.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_attached_hanging_sign_rot_2", + "textures": { + "all": "wild_wind_wilderness:block/blaze_hanging_sign", + "particle": "wild_wind_wilderness:block/stripped_blaze_log" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_hanging_sign_attached_rot_3.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_hanging_sign_attached_rot_3.json new file mode 100644 index 0000000..797b8a6 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_hanging_sign_attached_rot_3.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_attached_hanging_sign_rot_3", + "textures": { + "all": "wild_wind_wilderness:block/blaze_hanging_sign", + "particle": "wild_wind_wilderness:block/stripped_blaze_log" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_hanging_sign_rot_0.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_hanging_sign_rot_0.json new file mode 100644 index 0000000..72e8381 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_hanging_sign_rot_0.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_hanging_sign_rot_0", + "textures": { + "all": "wild_wind_wilderness:block/blaze_hanging_sign", + "particle": "wild_wind_wilderness:block/stripped_blaze_log" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_hanging_sign_rot_1.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_hanging_sign_rot_1.json new file mode 100644 index 0000000..7d4add0 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_hanging_sign_rot_1.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_hanging_sign_rot_1", + "textures": { + "all": "wild_wind_wilderness:block/blaze_hanging_sign", + "particle": "wild_wind_wilderness:block/stripped_blaze_log" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_hanging_sign_rot_2.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_hanging_sign_rot_2.json new file mode 100644 index 0000000..a9f34e6 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_hanging_sign_rot_2.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_hanging_sign_rot_2", + "textures": { + "all": "wild_wind_wilderness:block/blaze_hanging_sign", + "particle": "wild_wind_wilderness:block/stripped_blaze_log" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_hanging_sign_rot_3.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_hanging_sign_rot_3.json new file mode 100644 index 0000000..eee932a --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_hanging_sign_rot_3.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_hanging_sign_rot_3", + "textures": { + "all": "wild_wind_wilderness:block/blaze_hanging_sign", + "particle": "wild_wind_wilderness:block/stripped_blaze_log" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_leaves.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_leaves.json new file mode 100644 index 0000000..9c780b0 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_leaves.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cube_all", + "textures": { + "all": "wild_wind_wilderness:block/blaze_leaves" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_log.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_log.json new file mode 100644 index 0000000..e392f03 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_log.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/cube_column", + "textures": { + "end": "wild_wind_wilderness:block/blaze_log_top", + "side": "wild_wind_wilderness:block/blaze_log" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_log_horizontal.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_log_horizontal.json new file mode 100644 index 0000000..086ba20 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_log_horizontal.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/cube_column_horizontal", + "textures": { + "end": "wild_wind_wilderness:block/blaze_log_top", + "side": "wild_wind_wilderness:block/blaze_log" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_planks.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_planks.json new file mode 100644 index 0000000..94908b5 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_planks.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cube_all", + "textures": { + "all": "wild_wind_wilderness:block/blaze_planks" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_pressure_plate.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_pressure_plate.json new file mode 100644 index 0000000..c60c0ab --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_pressure_plate.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/pressure_plate_up", + "textures": { + "texture": "wild_wind_wilderness:block/blaze_planks" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_pressure_plate_down.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_pressure_plate_down.json new file mode 100644 index 0000000..1c480c6 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_pressure_plate_down.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/pressure_plate_down", + "textures": { + "texture": "wild_wind_wilderness:block/blaze_planks" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_sapling.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_sapling.json new file mode 100644 index 0000000..898a488 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_sapling.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cross", + "textures": { + "cross": "wild_wind_wilderness:block/blaze_sapling" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_sign_rot_0.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_sign_rot_0.json new file mode 100644 index 0000000..9bb8226 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_sign_rot_0.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_sign_rot_0", + "textures": { + "all": "wild_wind_wilderness:block/blaze_sign", + "particle": "wild_wind_wilderness:block/blaze_planks" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_sign_rot_1.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_sign_rot_1.json new file mode 100644 index 0000000..46a4f93 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_sign_rot_1.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_sign_rot_1", + "textures": { + "all": "wild_wind_wilderness:block/blaze_sign", + "particle": "wild_wind_wilderness:block/blaze_planks" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_sign_rot_2.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_sign_rot_2.json new file mode 100644 index 0000000..6973442 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_sign_rot_2.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_sign_rot_2", + "textures": { + "all": "wild_wind_wilderness:block/blaze_sign", + "particle": "wild_wind_wilderness:block/blaze_planks" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_sign_rot_3.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_sign_rot_3.json new file mode 100644 index 0000000..167036b --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_sign_rot_3.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_sign_rot_3", + "textures": { + "all": "wild_wind_wilderness:block/blaze_sign", + "particle": "wild_wind_wilderness:block/blaze_planks" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_slab.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_slab.json new file mode 100644 index 0000000..cfbd25e --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_slab.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/slab", + "textures": { + "bottom": "wild_wind_wilderness:block/blaze_planks", + "side": "wild_wind_wilderness:block/blaze_planks", + "top": "wild_wind_wilderness:block/blaze_planks" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_slab_top.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_slab_top.json new file mode 100644 index 0000000..185b45f --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_slab_top.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/slab_top", + "textures": { + "bottom": "wild_wind_wilderness:block/blaze_planks", + "side": "wild_wind_wilderness:block/blaze_planks", + "top": "wild_wind_wilderness:block/blaze_planks" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_stairs.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_stairs.json new file mode 100644 index 0000000..ca40832 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_stairs.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/stairs", + "textures": { + "bottom": "wild_wind_wilderness:block/blaze_planks", + "side": "wild_wind_wilderness:block/blaze_planks", + "top": "wild_wind_wilderness:block/blaze_planks" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_stairs_inner.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_stairs_inner.json new file mode 100644 index 0000000..6a37521 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_stairs_inner.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/inner_stairs", + "textures": { + "bottom": "wild_wind_wilderness:block/blaze_planks", + "side": "wild_wind_wilderness:block/blaze_planks", + "top": "wild_wind_wilderness:block/blaze_planks" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_stairs_outer.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_stairs_outer.json new file mode 100644 index 0000000..478809a --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_stairs_outer.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/outer_stairs", + "textures": { + "bottom": "wild_wind_wilderness:block/blaze_planks", + "side": "wild_wind_wilderness:block/blaze_planks", + "top": "wild_wind_wilderness:block/blaze_planks" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_trapdoor_bottom.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_trapdoor_bottom.json new file mode 100644 index 0000000..dcd4300 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_trapdoor_bottom.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/template_trapdoor_bottom", + "textures": { + "texture": "wild_wind_wilderness:block/blaze_trapdoor" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_trapdoor_open.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_trapdoor_open.json new file mode 100644 index 0000000..2b03dbd --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_trapdoor_open.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/template_trapdoor_open", + "textures": { + "texture": "wild_wind_wilderness:block/blaze_trapdoor" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_trapdoor_top.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_trapdoor_top.json new file mode 100644 index 0000000..75f0c70 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_trapdoor_top.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/template_trapdoor_top", + "textures": { + "texture": "wild_wind_wilderness:block/blaze_trapdoor" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_wall_hanging_sign.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_wall_hanging_sign.json new file mode 100644 index 0000000..fdfc3fb --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_wall_hanging_sign.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_wall_hanging_sign", + "textures": { + "all": "wild_wind_wilderness:block/blaze_hanging_sign", + "particle": "wild_wind_wilderness:block/stripped_blaze_log" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_wall_sign.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_wall_sign.json new file mode 100644 index 0000000..4723444 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_wall_sign.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_wall_sign", + "textures": { + "all": "wild_wind_wilderness:block/blaze_sign", + "particle": "wild_wind_wilderness:block/blaze_planks" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_wood.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_wood.json new file mode 100644 index 0000000..c4a016f --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/blaze_wood.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/cube_column", + "textures": { + "end": "wild_wind_wilderness:block/blaze_log", + "side": "wild_wind_wilderness:block/blaze_log" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/potted_blaze_sapling.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/potted_blaze_sapling.json new file mode 100644 index 0000000..e2561ff --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/potted_blaze_sapling.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/flower_pot_cross", + "textures": { + "plant": "wild_wind_wilderness:block/blaze_sapling" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/potted_soul_sapling.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/potted_soul_sapling.json new file mode 100644 index 0000000..d3c82d8 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/potted_soul_sapling.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/flower_pot_cross", + "textures": { + "plant": "wild_wind_wilderness:block/soul_sapling" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/scorched_dirt.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/scorched_dirt.json new file mode 100644 index 0000000..13d798b --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/scorched_dirt.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cube_all", + "textures": { + "all": "wild_wind_wilderness:block/scorched_dirt" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/scorched_grass.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/scorched_grass.json new file mode 100644 index 0000000..816d886 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/scorched_grass.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cross", + "textures": { + "cross": "wild_wind_wilderness:block/scorched_grass" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/scorched_grass_block.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/scorched_grass_block.json new file mode 100644 index 0000000..be13bcf --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/scorched_grass_block.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cube_all", + "textures": { + "all": "wild_wind_wilderness:block/scorched_grass_block" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/scorched_twig.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/scorched_twig.json new file mode 100644 index 0000000..b9b573e --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/scorched_twig.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cross", + "textures": { + "cross": "wild_wind_wilderness:block/scorched_twig" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_button.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_button.json new file mode 100644 index 0000000..c241126 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_button.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/button", + "textures": { + "texture": "wild_wind_wilderness:block/soul_planks" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_button_inventory.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_button_inventory.json new file mode 100644 index 0000000..05dbf63 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_button_inventory.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/button_inventory", + "textures": { + "texture": "wild_wind_wilderness:block/soul_planks" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_button_pressed.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_button_pressed.json new file mode 100644 index 0000000..d5a8a38 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_button_pressed.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/button_pressed", + "textures": { + "texture": "wild_wind_wilderness:block/soul_planks" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_door_bottom_left.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_door_bottom_left.json new file mode 100644 index 0000000..f281480 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_door_bottom_left.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/door_bottom_left", + "textures": { + "bottom": "wild_wind_wilderness:block/soul_door_bottom", + "top": "wild_wind_wilderness:block/soul_door_top" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_door_bottom_left_open.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_door_bottom_left_open.json new file mode 100644 index 0000000..a51d288 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_door_bottom_left_open.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/door_bottom_left_open", + "textures": { + "bottom": "wild_wind_wilderness:block/soul_door_bottom", + "top": "wild_wind_wilderness:block/soul_door_top" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_door_bottom_right.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_door_bottom_right.json new file mode 100644 index 0000000..c177899 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_door_bottom_right.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/door_bottom_right", + "textures": { + "bottom": "wild_wind_wilderness:block/soul_door_bottom", + "top": "wild_wind_wilderness:block/soul_door_top" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_door_bottom_right_open.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_door_bottom_right_open.json new file mode 100644 index 0000000..92d2249 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_door_bottom_right_open.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/door_bottom_right_open", + "textures": { + "bottom": "wild_wind_wilderness:block/soul_door_bottom", + "top": "wild_wind_wilderness:block/soul_door_top" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_door_top_left.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_door_top_left.json new file mode 100644 index 0000000..dc2154b --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_door_top_left.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/door_top_left", + "textures": { + "bottom": "wild_wind_wilderness:block/soul_door_bottom", + "top": "wild_wind_wilderness:block/soul_door_top" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_door_top_left_open.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_door_top_left_open.json new file mode 100644 index 0000000..b7409d2 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_door_top_left_open.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/door_top_left_open", + "textures": { + "bottom": "wild_wind_wilderness:block/soul_door_bottom", + "top": "wild_wind_wilderness:block/soul_door_top" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_door_top_right.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_door_top_right.json new file mode 100644 index 0000000..d01e523 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_door_top_right.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/door_top_right", + "textures": { + "bottom": "wild_wind_wilderness:block/soul_door_bottom", + "top": "wild_wind_wilderness:block/soul_door_top" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_door_top_right_open.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_door_top_right_open.json new file mode 100644 index 0000000..72d2328 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_door_top_right_open.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/door_top_right_open", + "textures": { + "bottom": "wild_wind_wilderness:block/soul_door_bottom", + "top": "wild_wind_wilderness:block/soul_door_top" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_fence_gate.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_fence_gate.json new file mode 100644 index 0000000..429bc5b --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_fence_gate.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/template_fence_gate", + "textures": { + "texture": "wild_wind_wilderness:block/soul_planks" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_fence_gate_open.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_fence_gate_open.json new file mode 100644 index 0000000..c3c1d6f --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_fence_gate_open.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/template_fence_gate_open", + "textures": { + "texture": "wild_wind_wilderness:block/soul_planks" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_fence_gate_wall.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_fence_gate_wall.json new file mode 100644 index 0000000..a3437e9 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_fence_gate_wall.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/template_fence_gate_wall", + "textures": { + "texture": "wild_wind_wilderness:block/soul_planks" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_fence_gate_wall_open.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_fence_gate_wall_open.json new file mode 100644 index 0000000..bd87de5 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_fence_gate_wall_open.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/template_fence_gate_wall_open", + "textures": { + "texture": "wild_wind_wilderness:block/soul_planks" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_fence_inventory.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_fence_inventory.json new file mode 100644 index 0000000..5cb2904 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_fence_inventory.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/fence_inventory", + "textures": { + "texture": "wild_wind_wilderness:block/soul_planks" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_fence_post.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_fence_post.json new file mode 100644 index 0000000..e0126f2 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_fence_post.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/fence_post", + "textures": { + "texture": "wild_wind_wilderness:block/soul_planks" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_fence_side.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_fence_side.json new file mode 100644 index 0000000..a3b6314 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_fence_side.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/fence_side", + "textures": { + "texture": "wild_wind_wilderness:block/soul_planks" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_hanging_sign_attached_rot_0.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_hanging_sign_attached_rot_0.json new file mode 100644 index 0000000..e7d4bb5 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_hanging_sign_attached_rot_0.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_attached_hanging_sign_rot_0", + "textures": { + "all": "wild_wind_wilderness:block/soul_hanging_sign", + "particle": "wild_wind_wilderness:block/stripped_soul_log" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_hanging_sign_attached_rot_1.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_hanging_sign_attached_rot_1.json new file mode 100644 index 0000000..41355bd --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_hanging_sign_attached_rot_1.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_attached_hanging_sign_rot_1", + "textures": { + "all": "wild_wind_wilderness:block/soul_hanging_sign", + "particle": "wild_wind_wilderness:block/stripped_soul_log" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_hanging_sign_attached_rot_2.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_hanging_sign_attached_rot_2.json new file mode 100644 index 0000000..3ceb1e1 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_hanging_sign_attached_rot_2.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_attached_hanging_sign_rot_2", + "textures": { + "all": "wild_wind_wilderness:block/soul_hanging_sign", + "particle": "wild_wind_wilderness:block/stripped_soul_log" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_hanging_sign_attached_rot_3.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_hanging_sign_attached_rot_3.json new file mode 100644 index 0000000..e5e37d5 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_hanging_sign_attached_rot_3.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_attached_hanging_sign_rot_3", + "textures": { + "all": "wild_wind_wilderness:block/soul_hanging_sign", + "particle": "wild_wind_wilderness:block/stripped_soul_log" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_hanging_sign_rot_0.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_hanging_sign_rot_0.json new file mode 100644 index 0000000..391b31b --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_hanging_sign_rot_0.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_hanging_sign_rot_0", + "textures": { + "all": "wild_wind_wilderness:block/soul_hanging_sign", + "particle": "wild_wind_wilderness:block/stripped_soul_log" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_hanging_sign_rot_1.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_hanging_sign_rot_1.json new file mode 100644 index 0000000..298cca0 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_hanging_sign_rot_1.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_hanging_sign_rot_1", + "textures": { + "all": "wild_wind_wilderness:block/soul_hanging_sign", + "particle": "wild_wind_wilderness:block/stripped_soul_log" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_hanging_sign_rot_2.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_hanging_sign_rot_2.json new file mode 100644 index 0000000..b776ba6 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_hanging_sign_rot_2.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_hanging_sign_rot_2", + "textures": { + "all": "wild_wind_wilderness:block/soul_hanging_sign", + "particle": "wild_wind_wilderness:block/stripped_soul_log" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_hanging_sign_rot_3.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_hanging_sign_rot_3.json new file mode 100644 index 0000000..a431f7b --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_hanging_sign_rot_3.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_hanging_sign_rot_3", + "textures": { + "all": "wild_wind_wilderness:block/soul_hanging_sign", + "particle": "wild_wind_wilderness:block/stripped_soul_log" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_leaves.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_leaves.json new file mode 100644 index 0000000..63842c4 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_leaves.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cube_all", + "textures": { + "all": "wild_wind_wilderness:block/soul_leaves" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_log.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_log.json new file mode 100644 index 0000000..ae7d7cb --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_log.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/cube_column", + "textures": { + "end": "wild_wind_wilderness:block/soul_log_top", + "side": "wild_wind_wilderness:block/soul_log" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_log_horizontal.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_log_horizontal.json new file mode 100644 index 0000000..a23b551 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_log_horizontal.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/cube_column_horizontal", + "textures": { + "end": "wild_wind_wilderness:block/soul_log_top", + "side": "wild_wind_wilderness:block/soul_log" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_planks.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_planks.json new file mode 100644 index 0000000..0c535c5 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_planks.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cube_all", + "textures": { + "all": "wild_wind_wilderness:block/soul_planks" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_pressure_plate.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_pressure_plate.json new file mode 100644 index 0000000..507ef51 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_pressure_plate.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/pressure_plate_up", + "textures": { + "texture": "wild_wind_wilderness:block/soul_planks" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_pressure_plate_down.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_pressure_plate_down.json new file mode 100644 index 0000000..330ae3a --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_pressure_plate_down.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/pressure_plate_down", + "textures": { + "texture": "wild_wind_wilderness:block/soul_planks" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_sapling.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_sapling.json new file mode 100644 index 0000000..efa7077 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_sapling.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cross", + "textures": { + "cross": "wild_wind_wilderness:block/soul_sapling" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_sign_rot_0.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_sign_rot_0.json new file mode 100644 index 0000000..5d176d8 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_sign_rot_0.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_sign_rot_0", + "textures": { + "all": "wild_wind_wilderness:block/soul_sign", + "particle": "wild_wind_wilderness:block/soul_planks" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_sign_rot_1.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_sign_rot_1.json new file mode 100644 index 0000000..2f39d93 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_sign_rot_1.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_sign_rot_1", + "textures": { + "all": "wild_wind_wilderness:block/soul_sign", + "particle": "wild_wind_wilderness:block/soul_planks" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_sign_rot_2.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_sign_rot_2.json new file mode 100644 index 0000000..f5facd8 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_sign_rot_2.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_sign_rot_2", + "textures": { + "all": "wild_wind_wilderness:block/soul_sign", + "particle": "wild_wind_wilderness:block/soul_planks" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_sign_rot_3.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_sign_rot_3.json new file mode 100644 index 0000000..0212116 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_sign_rot_3.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_sign_rot_3", + "textures": { + "all": "wild_wind_wilderness:block/soul_sign", + "particle": "wild_wind_wilderness:block/soul_planks" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_slab.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_slab.json new file mode 100644 index 0000000..56a8819 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_slab.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/slab", + "textures": { + "bottom": "wild_wind_wilderness:block/soul_planks", + "side": "wild_wind_wilderness:block/soul_planks", + "top": "wild_wind_wilderness:block/soul_planks" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_slab_top.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_slab_top.json new file mode 100644 index 0000000..e719b47 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_slab_top.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/slab_top", + "textures": { + "bottom": "wild_wind_wilderness:block/soul_planks", + "side": "wild_wind_wilderness:block/soul_planks", + "top": "wild_wind_wilderness:block/soul_planks" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_stairs.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_stairs.json new file mode 100644 index 0000000..7f95cb2 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_stairs.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/stairs", + "textures": { + "bottom": "wild_wind_wilderness:block/soul_planks", + "side": "wild_wind_wilderness:block/soul_planks", + "top": "wild_wind_wilderness:block/soul_planks" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_stairs_inner.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_stairs_inner.json new file mode 100644 index 0000000..6fd1826 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_stairs_inner.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/inner_stairs", + "textures": { + "bottom": "wild_wind_wilderness:block/soul_planks", + "side": "wild_wind_wilderness:block/soul_planks", + "top": "wild_wind_wilderness:block/soul_planks" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_stairs_outer.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_stairs_outer.json new file mode 100644 index 0000000..576e38e --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_stairs_outer.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/outer_stairs", + "textures": { + "bottom": "wild_wind_wilderness:block/soul_planks", + "side": "wild_wind_wilderness:block/soul_planks", + "top": "wild_wind_wilderness:block/soul_planks" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_trapdoor_bottom.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_trapdoor_bottom.json new file mode 100644 index 0000000..8c2c02e --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_trapdoor_bottom.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/template_trapdoor_bottom", + "textures": { + "texture": "wild_wind_wilderness:block/soul_trapdoor" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_trapdoor_open.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_trapdoor_open.json new file mode 100644 index 0000000..41da92d --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_trapdoor_open.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/template_trapdoor_open", + "textures": { + "texture": "wild_wind_wilderness:block/soul_trapdoor" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_trapdoor_top.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_trapdoor_top.json new file mode 100644 index 0000000..b246108 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_trapdoor_top.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/template_trapdoor_top", + "textures": { + "texture": "wild_wind_wilderness:block/soul_trapdoor" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_wall_hanging_sign.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_wall_hanging_sign.json new file mode 100644 index 0000000..ee0bcd1 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_wall_hanging_sign.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_wall_hanging_sign", + "textures": { + "all": "wild_wind_wilderness:block/soul_hanging_sign", + "particle": "wild_wind_wilderness:block/stripped_soul_log" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_wall_sign.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_wall_sign.json new file mode 100644 index 0000000..60b567e --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_wall_sign.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/template_wall_sign", + "textures": { + "all": "wild_wind_wilderness:block/soul_sign", + "particle": "wild_wind_wilderness:block/soul_planks" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_wood.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_wood.json new file mode 100644 index 0000000..1ff6400 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/soul_wood.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/cube_column", + "textures": { + "end": "wild_wind_wilderness:block/soul_log", + "side": "wild_wind_wilderness:block/soul_log" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/stripped_blaze_log.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/stripped_blaze_log.json new file mode 100644 index 0000000..aa60b01 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/stripped_blaze_log.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/cube_column", + "textures": { + "end": "wild_wind_wilderness:block/stripped_blaze_log_top", + "side": "wild_wind_wilderness:block/stripped_blaze_log" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/stripped_blaze_log_horizontal.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/stripped_blaze_log_horizontal.json new file mode 100644 index 0000000..7e2bcf2 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/stripped_blaze_log_horizontal.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/cube_column_horizontal", + "textures": { + "end": "wild_wind_wilderness:block/stripped_blaze_log_top", + "side": "wild_wind_wilderness:block/stripped_blaze_log" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/stripped_blaze_wood.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/stripped_blaze_wood.json new file mode 100644 index 0000000..ac6c82e --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/stripped_blaze_wood.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/cube_column", + "textures": { + "end": "wild_wind_wilderness:block/stripped_blaze_log", + "side": "wild_wind_wilderness:block/stripped_blaze_log" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/stripped_soul_log.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/stripped_soul_log.json new file mode 100644 index 0000000..058a893 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/stripped_soul_log.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/cube_column", + "textures": { + "end": "wild_wind_wilderness:block/stripped_soul_log_top", + "side": "wild_wind_wilderness:block/stripped_soul_log" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/stripped_soul_log_horizontal.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/stripped_soul_log_horizontal.json new file mode 100644 index 0000000..6a0c505 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/stripped_soul_log_horizontal.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/cube_column_horizontal", + "textures": { + "end": "wild_wind_wilderness:block/stripped_soul_log_top", + "side": "wild_wind_wilderness:block/stripped_soul_log" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/block/stripped_soul_wood.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/stripped_soul_wood.json new file mode 100644 index 0000000..212b94f --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/block/stripped_soul_wood.json @@ -0,0 +1,7 @@ +{ + "parent": "minecraft:block/cube_column", + "textures": { + "end": "wild_wind_wilderness:block/stripped_soul_log", + "side": "wild_wind_wilderness:block/stripped_soul_log" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/entity/pig/pig_muddy.bbmodel b/src/wilderness/resources/assets/wild_wind_wilderness/models/entity/pig/pig_muddy.bbmodel new file mode 100644 index 0000000..9b3c306 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/entity/pig/pig_muddy.bbmodel @@ -0,0 +1 @@ +{"meta":{"format_version":"5.0","model_format":"modded_entity","box_uv":true},"name":"pig_muddy","model_identifier":"","modded_entity_entity_class":"","modded_entity_version":"1.17","modded_entity_flip_y":true,"visible_box":[1,1,0],"variable_placeholders":"","multi_file_ruleset":"","variable_placeholder_buttons":[],"timeline_setups":[],"unhandled_root_fields":{},"resolution":{"width":64,"height":64},"elements":[{"name":"body","box_uv":true,"render_order":"default","locked":false,"export":true,"scope":0,"allow_mirror_modeling":true,"from":[-5,18,10],"to":[5,34,18],"autouv":0,"color":5,"rotation":[-90,0,0],"origin":[0,11,15],"uv_offset":[28,8],"faces":{"north":{"uv":[36,16,46,32],"texture":0},"east":{"uv":[28,16,36,32],"texture":0},"south":{"uv":[54,16,64,32],"texture":0},"west":{"uv":[46,16,54,32],"texture":0},"up":{"uv":[46,16,36,8],"texture":0},"down":{"uv":[56,8,46,16],"texture":0}},"type":"cube","uuid":"bf06d62a-bc20-e9e6-67f6-1f12ac271a15"},{"name":"head","box_uv":true,"render_order":"default","locked":false,"export":true,"scope":0,"allow_mirror_modeling":true,"from":[-4,10,-15],"to":[4,18,-7],"autouv":0,"color":0,"origin":[0,2,-1],"faces":{"north":{"uv":[8,8,16,16],"texture":0},"east":{"uv":[0,8,8,16],"texture":0},"south":{"uv":[24,8,32,16],"texture":0},"west":{"uv":[16,8,24,16],"texture":0},"up":{"uv":[16,8,8,0],"texture":0},"down":{"uv":[24,0,16,8],"texture":0}},"type":"cube","uuid":"104bcae4-e56b-5454-d491-ad60a837caff"},{"name":"head","box_uv":true,"render_order":"default","locked":false,"export":true,"scope":0,"allow_mirror_modeling":true,"from":[-2,11,-16],"to":[2,14,-15],"autouv":0,"color":6,"origin":[0,2,-1],"uv_offset":[16,16],"faces":{"north":{"uv":[17,17,21,20],"texture":0},"east":{"uv":[16,17,17,20],"texture":0},"south":{"uv":[22,17,26,20],"texture":0},"west":{"uv":[21,17,22,20],"texture":0},"up":{"uv":[21,17,17,16],"texture":0},"down":{"uv":[25,16,21,17],"texture":0}},"type":"cube","uuid":"5598eebe-0524-bee6-41e9-9d6a06944398"},{"name":"leg1","box_uv":true,"render_order":"default","locked":false,"export":true,"scope":0,"allow_mirror_modeling":true,"from":[1,0,4],"to":[5,6,8],"autouv":0,"color":7,"origin":[0,0,-1],"uv_offset":[0,16],"faces":{"north":{"uv":[4,20,8,26],"texture":0},"east":{"uv":[0,20,4,26],"texture":0},"south":{"uv":[12,20,16,26],"texture":0},"west":{"uv":[8,20,12,26],"texture":0},"up":{"uv":[8,20,4,16],"texture":0},"down":{"uv":[12,16,8,20],"texture":0}},"type":"cube","uuid":"4a928788-a75a-920b-75d6-7cfce294e760"},{"name":"leg2","box_uv":true,"render_order":"default","locked":false,"export":true,"scope":0,"allow_mirror_modeling":true,"from":[-5,0,4],"to":[-1,6,8],"autouv":0,"color":8,"origin":[0,0,-1],"uv_offset":[0,16],"faces":{"north":{"uv":[4,20,8,26],"texture":0},"east":{"uv":[0,20,4,26],"texture":0},"south":{"uv":[12,20,16,26],"texture":0},"west":{"uv":[8,20,12,26],"texture":0},"up":{"uv":[8,20,4,16],"texture":0},"down":{"uv":[12,16,8,20],"texture":0}},"type":"cube","uuid":"a60ed14f-f7cb-b9c6-4cdf-162149716218"},{"name":"leg3","box_uv":true,"render_order":"default","locked":false,"export":true,"scope":0,"allow_mirror_modeling":true,"from":[1,0,-8],"to":[5,6,-4],"autouv":0,"color":7,"origin":[0,0,-1],"uv_offset":[0,16],"faces":{"north":{"uv":[4,20,8,26],"texture":0},"east":{"uv":[0,20,4,26],"texture":0},"south":{"uv":[12,20,16,26],"texture":0},"west":{"uv":[8,20,12,26],"texture":0},"up":{"uv":[8,20,4,16],"texture":0},"down":{"uv":[12,16,8,20],"texture":0}},"type":"cube","uuid":"99988f96-0a9e-7a17-7ef5-4c60895252e5"},{"name":"leg4","box_uv":true,"render_order":"default","locked":false,"export":true,"scope":0,"allow_mirror_modeling":true,"from":[-5,0,-8],"to":[-1,6,-4],"autouv":0,"color":5,"origin":[0,0,-1],"uv_offset":[0,16],"faces":{"north":{"uv":[4,20,8,26],"texture":0},"east":{"uv":[0,20,4,26],"texture":0},"south":{"uv":[12,20,16,26],"texture":0},"west":{"uv":[8,20,12,26],"texture":0},"up":{"uv":[8,20,4,16],"texture":0},"down":{"uv":[12,16,8,20],"texture":0}},"type":"cube","uuid":"6558fe05-2fa6-c177-4217-2ea245c35cf0"},{"name":"cube","box_uv":true,"render_order":"default","locked":false,"export":true,"scope":0,"allow_mirror_modeling":true,"from":[0,18,-16],"to":[0,24,-10],"autouv":0,"color":9,"origin":[0,18,-16],"uv_offset":[24,-4],"faces":{"north":{"uv":[30,2,30,8],"texture":0},"east":{"uv":[24,2,30,8],"texture":0},"south":{"uv":[36,2,36,8],"texture":0},"west":{"uv":[30,2,36,8],"texture":0},"up":{"uv":[30,2,30,-4],"texture":0},"down":{"uv":[30,-4,30,2],"texture":0}},"type":"cube","uuid":"f2f49590-f333-6170-0f0e-b2f7bb0880e2"},{"name":"cube","box_uv":true,"render_order":"default","locked":false,"export":true,"scope":0,"allow_mirror_modeling":true,"from":[-3,18,-13],"to":[3,24,-13],"autouv":1,"color":5,"origin":[3,18,-13],"uv_offset":[24,2],"faces":{"north":{"uv":[24,2,30,8],"texture":0},"east":{"uv":[24,2,24,8],"texture":0},"south":{"uv":[30,2,36,8],"texture":0},"west":{"uv":[30,2,30,8],"texture":0},"up":{"uv":[30,2,24,2],"texture":0},"down":{"uv":[36,2,30,2],"texture":0}},"type":"cube","uuid":"dd45f095-2a2b-639e-0e43-41ed79b7122b"}],"groups":[],"outliner":["bf06d62a-bc20-e9e6-67f6-1f12ac271a15","104bcae4-e56b-5454-d491-ad60a837caff","5598eebe-0524-bee6-41e9-9d6a06944398","4a928788-a75a-920b-75d6-7cfce294e760","a60ed14f-f7cb-b9c6-4cdf-162149716218","99988f96-0a9e-7a17-7ef5-4c60895252e5","6558fe05-2fa6-c177-4217-2ea245c35cf0","f2f49590-f333-6170-0f0e-b2f7bb0880e2","dd45f095-2a2b-639e-0e43-41ed79b7122b"],"textures":[{"name":"pig_muddy.png","relative_path":"pig_muddy.png","folder":"","namespace":"","id":"1","group":"","scope":0,"width":64,"height":64,"uv_width":64,"uv_height":64,"particle":false,"use_as_default":false,"layers_enabled":false,"sync_to_project":"","file_format":"png","render_mode":"default","render_sides":"auto","wrap_mode":"limited","pbr_channel":"color","fps":7,"frame_time":1,"frame_order_type":"loop","frame_order":"","frame_interpolate":false,"visible":true,"internal":true,"saved":true,"uuid":"cda7bb44-a55d-8fa7-6bae-96ec4cb7826f","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAHPklEQVR4AeyYf4hUVRTHzzz/0GV2yiWNVfxjKyRry2JJhQWF2P4oFJT6IwiCKCPBSKGypJIgLSqkBLWVSsFKEFIK6h9xk1QW1NrIEE2LNtPdqRV/5K6uxDq9z505s3eub+bNqMw8h7fsd86559e957wz9955noT89a15P3NuY6fB6S8+L6DoHpranCmFkPA1V4cWIJlKycjYxsCFJlOpQPmNJAwtgJuMFmPPLwdcVdHxwfmzRlAqhY8Kyi6Am3D7Aw8W5JBsGFcwtgd96f9kze2tI1BbHgW+rAJ0/7BLPu7qkmXrVhkw1sW7idtjm1f7qNGyCkDyExsbzNpvbRwnX+3rNrz9MXRx2B7m+de3dYzsXdYkd04cKw/v6xmTV0SE8cpZB8mTOPhn8MpE7SethVDZyse6xgykRdbf3yDPresYAeXMWS2bsgrgLmZg8KKMuTRoxHbCJK1AqboNi7vMk7/wd0aURx8FeH2r3spwngP7vNczX3d9e7HPdnTkj8Zty9+UTa+sNNi89FVRfPTMYtn81GIhLui8e4H37i2PePA27LjwfctfzJQNa+12TMOj82MRsxQKOmDo/HkBPF1A8tAFs9qF1gcEm33vDIgpgtpghxB/AF8VBHwlJUhWZDGeDJ4tVKXTcn7/wXwhSKatZZqsXrjEgGLgMHyqXwCJY2N8jh1DNQpil1pMKd1olHDOj3Nk124BJN9zqjfcJ2eR7QA/QG5syPFLZ+Xy4T9MEaYsWSaTXnjJ8EP9A9I2ocXwyNCRPLb4GGf9cGKqOIz2DPsPpHF83mxH+s88bxhfh41BLtEjB/bL8aaxMm3GTPls9x6zRmyxgZZCrgD+pI6V15Q99k6seU/+3bQhq/WPQPGRTKWMDB0KtYXPg6evg6BiBMl8e47YFd9uERJf++N3cvTk7740+48MHTaKHb/9LDsvnDB2JP/knNmCTO2ynsU/Papk0Hskb9XSPEmkuVl6fBngKatSx8jgAbbGJ2eEzMTkaWohSNgGtqqDz4ETBpA4ew6gEGDvr4eMFXqFbXcuMyBrv98utp1xKPHhdR/qyatZOBOBFVs3mtsflyB4hT2GB+jwAcTQgMTuTffL5b/6xew1JJwDMnRq61ISR0aiNs8YucLW2bxrp/YuNV8BFqotdSh9RgABOMcBvMIewwN0+ACNQ0ydjP2BZC+fuSgAHpnqbUo8xsQEjKHERg6QKdABxlDXDnsbLu+9veOnBPik+3ACEAhgyKUGClS281g68fXBXgN48OWHG/PnP6cFN0Z8wDcnD0v7pi0JMKVzfSI1c7q0zp5jcHp8gyxsvyszf3qLAe8V8NG54O01MA7ScVNdOm9ufg16F+GOoncbKHcbBWNgOoDANtxJbZ3Lc+m40Hu0QPz83CeEoioKlNaA+8RtE24SEkCs8ypF5kJ1SvElBrFcW8bcU2wKD1QeWAAMgF1txsXQuXW7DPl3AI5J+GJ2yHViNlHG991xj9AxJMJYE2PuINg2+OBLDOQudC6l6Lm3QLnDQAMLoBNjEAp/Z1/0+KOSnDpVkpMmCjyXkTA/3SzZK3TzUh/mV96lrg5fYlBQ952F+mrSOlZKYTy+dzZUaVOdFGrbwk9+7Y3EzU8vKgAy29/lmZjbpSu/1rH9NWAOjUdxgnhknrYcA3gAD+ABPIAH8MDmGZeDYk+DHdz1D4sf5OPGCBt7fI+YCMADeAAP4AE8gAfwYROE6dtb2wr2ANuejrPHLs/87AHEcHU6LlZw1Zs9oLW5SYAK4Qluj5Hp+Fqo3ZrE4bcFlESglUB97NZX/7DEk6nsG20vqI3YWDSQTbEFKrN5lV0NZT5QqS8+wHzH/c24En8eBEUyHUAQQEK9A2fEpvDogE6gralU5eVSJlZb/enKPCorl6qPnihBfiQaJFeZx62OGyCA52ZnU3h0AB7YNhroaijHFkcYrWx/5YJisee4cnzwJYYW0rVxx8lUtvVVbjpAB9WgPH0S565QyVEY1m1t48ab9xQmdi4R5sqxhjDWjoBHWPUCMKlJ3PwqHBZ2cL5etHNYkvgqsMUHX2JIY/YliomtRj7VRH028L/qBTAbFkvJLZj2ZQi0zZUic6E6pejzMXIbIXMAdCCZGm17CgKQY1P1AjAx7Z+lV76JMnL/gwSD4KuC/+koNLkiMAe/TUgSsSYNjwwdNtUvAAtksT54a0QL08q0tIJFloLaQfElBrFGX7oMZ1/AiAhJmoRzb7zhkZn4/hqqXgB+J0x+Z3UCzPvgU/MOQk8WThfAuBSwUWDHCUUsYhr4v0/yFH7Jy4nJNpABfx1VL4CpfIQ+4gJE6GHUZClxB9Sk7BGaNO6ACD2Mmiwl7oCalD1Ck8YdEKGHUZOlxB1Qk7JHaNK4AyL0MK7LUioNEndApRWrN/u4A+rtiVaaT9wBlVas3uzjDqi3J1ppPnEHVFqxerOPO6Denmil+cQdUGnF6s0+7oAb/Yle6/r/BwAA//+JSasJAAAABklEQVQDAK7PNsya68vLAAAAAElFTkSuQmCC"}]} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/entity/pig/pig_muddy_baby.bbmodel b/src/wilderness/resources/assets/wild_wind_wilderness/models/entity/pig/pig_muddy_baby.bbmodel new file mode 100644 index 0000000..8ec8ecd --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/entity/pig/pig_muddy_baby.bbmodel @@ -0,0 +1 @@ +{"meta":{"format_version":"5.0","model_format":"modded_entity","box_uv":true},"name":"pig_muddy_baby","model_identifier":"","modded_entity_entity_class":"","modded_entity_version":"1.17","modded_entity_flip_y":true,"visible_box":[1,1,0],"variable_placeholders":"","multi_file_ruleset":"","variable_placeholder_buttons":[],"timeline_setups":[],"unhandled_root_fields":{},"resolution":{"width":32,"height":32},"elements":[{"name":"cube","box_uv":true,"render_order":"default","locked":false,"export":true,"scope":0,"allow_mirror_modeling":true,"from":[-3,4,-7],"to":[4,10,-1],"autouv":0,"color":8,"origin":[-6,4,-6],"uv_offset":[0,15],"faces":{"north":{"uv":[6,21,13,27],"texture":0},"east":{"uv":[0,21,6,27],"texture":0},"south":{"uv":[19,21,26,27],"texture":0},"west":{"uv":[13,21,19,27],"texture":0},"up":{"uv":[13,21,6,15],"texture":0},"down":{"uv":[20,15,13,21],"texture":0}},"type":"cube","uuid":"3203416e-91fd-5855-0f49-fb1a643c8509"},{"name":"cube","box_uv":true,"render_order":"default","locked":false,"export":true,"scope":0,"allow_mirror_modeling":true,"from":[-1,5,-8],"to":[2,7,-7],"autouv":0,"color":5,"origin":[0,5,-7],"uv_offset":[6,27],"faces":{"north":{"uv":[7,28,10,30],"texture":0},"east":{"uv":[6,28,7,30],"texture":0},"south":{"uv":[11,28,14,30],"texture":0},"west":{"uv":[10,28,11,30],"texture":0},"up":{"uv":[10,28,7,27],"texture":0},"down":{"uv":[13,27,10,28],"texture":0}},"type":"cube","uuid":"12f570c1-e40a-37d3-764e-2caaebd271be"},{"name":"cube","box_uv":true,"render_order":"default","locked":false,"export":true,"scope":0,"allow_mirror_modeling":true,"from":[-3,2,-4],"to":[4,8,5],"autouv":0,"color":7,"origin":[-2,2,-3],"faces":{"north":{"uv":[9,9,16,15],"texture":0},"east":{"uv":[0,9,9,15],"texture":0},"south":{"uv":[25,9,32,15],"texture":0},"west":{"uv":[16,9,25,15],"texture":0},"up":{"uv":[16,9,9,0],"texture":0},"down":{"uv":[23,0,16,9],"texture":0}},"type":"cube","uuid":"43168b76-dff2-f3e3-4b9d-73f150b67955"},{"name":"cube","box_uv":true,"render_order":"default","locked":false,"export":true,"scope":0,"allow_mirror_modeling":true,"from":[-3,0,3],"to":[-1,2,5],"autouv":1,"color":8,"origin":[-2,0,4],"faces":{"north":{"uv":[2,2,4,4],"texture":0},"east":{"uv":[0,2,2,4],"texture":0},"south":{"uv":[6,2,8,4],"texture":0},"west":{"uv":[4,2,6,4],"texture":0},"up":{"uv":[4,2,2,0],"texture":0},"down":{"uv":[6,0,4,2],"texture":0}},"type":"cube","uuid":"ef17ef72-dc6f-8353-890f-7ebd5b7d8a1c"},{"name":"cube","box_uv":true,"render_order":"default","locked":false,"export":true,"scope":0,"allow_mirror_modeling":true,"from":[2,0,3],"to":[4,2,5],"autouv":0,"color":7,"origin":[3,0,4],"uv_offset":[23,0],"faces":{"north":{"uv":[25,2,27,4],"texture":0},"east":{"uv":[23,2,25,4],"texture":0},"south":{"uv":[29,2,31,4],"texture":0},"west":{"uv":[27,2,29,4],"texture":0},"up":{"uv":[27,2,25,0],"texture":0},"down":{"uv":[29,0,27,2],"texture":0}},"type":"cube","uuid":"dfd1d3d4-d7f5-b90a-f896-746147985048"},{"name":"cube","box_uv":true,"render_order":"default","locked":false,"export":true,"scope":0,"allow_mirror_modeling":true,"from":[-3,0,-4],"to":[-1,2,-2],"autouv":0,"color":7,"origin":[-2,0,-3],"uv_offset":[0,4],"faces":{"north":{"uv":[2,6,4,8],"texture":0},"east":{"uv":[0,6,2,8],"texture":0},"south":{"uv":[6,6,8,8],"texture":0},"west":{"uv":[4,6,6,8],"texture":0},"up":{"uv":[4,6,2,4],"texture":0},"down":{"uv":[6,4,4,6],"texture":0}},"type":"cube","uuid":"e1e83bbd-5cf9-eeab-b415-28e003d26369"},{"name":"cube","box_uv":true,"render_order":"default","locked":false,"export":true,"scope":0,"allow_mirror_modeling":true,"from":[2,0,-4],"to":[4,2,-2],"autouv":0,"color":0,"origin":[3,0,-3],"uv_offset":[23,4],"faces":{"north":{"uv":[25,6,27,8],"texture":0},"east":{"uv":[23,6,25,8],"texture":0},"south":{"uv":[29,6,31,8],"texture":0},"west":{"uv":[27,6,29,8],"texture":0},"up":{"uv":[27,6,25,4],"texture":0},"down":{"uv":[29,4,27,6],"texture":0}},"type":"cube","uuid":"ddc8596c-5406-1c98-fa08-ca091cb600a2"},{"name":"cube","box_uv":true,"render_order":"default","locked":false,"export":true,"scope":0,"allow_mirror_modeling":true,"from":[1,10,-7],"to":[1,14,-4],"autouv":0,"color":9,"origin":[1,9,-7],"uv_offset":[0,14],"faces":{"north":{"uv":[3,17,3,21],"texture":0},"east":{"uv":[0,17,3,21],"texture":0},"south":{"uv":[6,17,6,21],"texture":0},"west":{"uv":[3,17,6,21],"texture":0},"up":{"uv":[3,17,3,14],"texture":0},"down":{"uv":[3,14,3,17],"texture":0}},"type":"cube","uuid":"440dd7b3-629b-e562-3a47-9e7348760aeb"},{"name":"cube","box_uv":true,"render_order":"default","locked":false,"export":true,"scope":0,"allow_mirror_modeling":true,"from":[-0.5,10,-5],"to":[2.5,14,-5],"autouv":0,"color":5,"origin":[2.5,9,-5],"uv_offset":[0,17],"faces":{"north":{"uv":[0,17,3,21],"texture":0},"east":{"uv":[0,17,0,21],"texture":0},"south":{"uv":[3,17,6,21],"texture":0},"west":{"uv":[3,17,3,21],"texture":0},"up":{"uv":[3,17,0,17],"texture":0},"down":{"uv":[6,17,3,17],"texture":0}},"type":"cube","uuid":"4070e32c-d428-1ea6-5e11-1c95798208d7"}],"groups":[],"outliner":["3203416e-91fd-5855-0f49-fb1a643c8509","12f570c1-e40a-37d3-764e-2caaebd271be","43168b76-dff2-f3e3-4b9d-73f150b67955","ef17ef72-dc6f-8353-890f-7ebd5b7d8a1c","dfd1d3d4-d7f5-b90a-f896-746147985048","e1e83bbd-5cf9-eeab-b415-28e003d26369","ddc8596c-5406-1c98-fa08-ca091cb600a2","440dd7b3-629b-e562-3a47-9e7348760aeb","4070e32c-d428-1ea6-5e11-1c95798208d7"],"textures":[{"name":"pig_muddy_baby.png","relative_path":"pig_muddy_baby.png","folder":"","namespace":"","id":"0","group":"","scope":0,"width":32,"height":32,"uv_width":16,"uv_height":16,"particle":false,"use_as_default":false,"layers_enabled":false,"sync_to_project":"","file_format":"png","render_mode":"default","render_sides":"auto","wrap_mode":"limited","pbr_channel":"color","fps":7,"frame_time":1,"frame_order_type":"loop","frame_order":"","frame_interpolate":false,"visible":true,"internal":true,"saved":true,"uuid":"28bb92f6-574c-6bf5-1456-af96835e15ca","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAEtklEQVR4AayWf2hVZRjHn/tuA02TjbhSfxhT6I+QhJCSRkWwimAjhVhCUGh0/wqM6I/CggZBmBBDAmsszSD8J8Utt6TsFpQsBmkwWFERGw5tuGzhb3Dz+Hyee5/Dueeec/3Bxvm+z/N+n1/v7vu87zlBqn/bn34wAk/ed3e0cV17VKVNXO3rjaKD++qxb3eEPyDGwRxYsA7kBdiTvJokXgCTPDS3rRRpvavWzPzOO4xbtnSJSR/Sc+ezZHil4/4InLlwRUB7sU2Ky5cKHLCgaiHTKWxKZfBiFy9fEQcWeOIBeQF5yQ8H8Atriq0CpmbnZOXyJaYzR4fDKRfVxVCYgu7HHJ08wHOhA/LC4RO2D/1cAA+vvoe5fP/bpIxN/iPvf/tr4bu/ZgpG+lAt6NOk9KJJjrwAjvxjmpf85CU//E31AI7y/1mJAeFz9ASSv0SCzlVvrgdywyuGZFF+CZ+zz4D9B4vfA5X6NlLUYYQO7Ddgv9l3dIAOpy4S94DvC3sG2CM4nBqB/zjLDk8e4LnQAXnhiAvxJVM+HEWO1KWDYx6O7tghg30fyeC7vRWgK45+MiB2eellZTU8d0LCB7tkNPvI8KCOqadB16c866Z1+Wha9Zo8cliA28P83BmlRboefcykDVp45NhPla5XwnSVPJ8PDyMMMa/JTdc4M+jg+cj/zclpZfRRvx/P/qdKpR582PnDESH47f5dYqtSJ+ToxImYHxwbldKHHwjF/zz1tyVAh7c4Xaz5D+uvWI13nvz44Q9H/OpHOiwXfJj895wQzDFB4oSBKkj42QuXBRz7Y0ImZuYEn0PHfzEOO37uj4088EjyeyxcOj5gxEACl84hAR2N3XWSMIeHA8Qi4dFdwiX90JPxYWh8qvDp6O8xOB5wA2+8WeluOnr/gYq+5wuh67/s7hHwdc+LJtF3P9FtOvHbiiuukRNJLo4dEqT1/KuYhlrRJnV/8CmyZf1aael8XJAcvQe2vRM40iYP6neEHsVUSDwN4xs3LDBDAteRSdCYyXmdrs1n3wytie8GOHXkJKjIfMLpmauya83aBSRw3b29cNcLW53Kll6Yoo5szxo2PDN2oqn8VKsceqlNkjpeI/s/Ezq89FpJ0OXcHLShUFwmDjl/yTgbWIhD+fmTU0bnDXEP9L9abnIn1ynuL42BctnNVpgJtyiwn3haLxv/z1WfHz8uxqtjNHtRx+wn0DRDz79lTUPjuC6pBix1dopzzevWC5BVqwSYnvxsU7353nZxtGiTZpeX2o9SW7Wu3Jz15960ocO+E5l3dW9CxIuo8a1YbmsMyf2bPnW6JsmzfXuF+4CF8DXU9JC+L3Rh7lTj32C/G/VB/DKiAInZU9N1PxfKX0HFLyqbK4/d/LAyV+n7reotPYE3kh81XhKi+8fLCVCIbKajaDF0gJ/5K088eVSV9H+bnuOTROCFQbeX9G3HiwRJxwN0kNZ97v7Ek8cTU9ThXJ4M3N3c28B17mww8N5OAXzxfNyzWbjvD2zdItiS/q63vN5byEPuAvIMHM+9/XtE9EwjOVIcJyS2vLhb5eOLKCvw5c169LQnTGY5LAKXu4DCc1sKjbAItS1F7gLMugjDjVJcBwAA//9Zy29CAAAABklEQVQDAG1bs256JTTFAAAAAElFTkSuQmCC"}]} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/item/blaze_boat.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/blaze_boat.json new file mode 100644 index 0000000..e129e75 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/blaze_boat.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wild_wind_wilderness:item/blaze_boat" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/item/blaze_chest_boat.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/blaze_chest_boat.json new file mode 100644 index 0000000..7021e4f --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/blaze_chest_boat.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wild_wind_wilderness:item/blaze_chest_boat" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/item/blaze_door.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/blaze_door.json new file mode 100644 index 0000000..f731b73 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/blaze_door.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wild_wind_wilderness:item/blaze_door" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/item/blaze_hanging_sign.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/blaze_hanging_sign.json new file mode 100644 index 0000000..2661357 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/blaze_hanging_sign.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wild_wind_wilderness:item/blaze_hanging_sign" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/item/blaze_sapling.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/blaze_sapling.json new file mode 100644 index 0000000..0c4da17 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/blaze_sapling.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wild_wind_wilderness:block/blaze_sapling" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/item/blaze_sign.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/blaze_sign.json new file mode 100644 index 0000000..d85a29f --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/blaze_sign.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wild_wind_wilderness:item/blaze_sign" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/item/cooked_piranha.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/cooked_piranha.json new file mode 100644 index 0000000..bb1529d --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/cooked_piranha.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wild_wind_wilderness:item/cooked_piranha" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/item/crab_claw.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/crab_claw.json new file mode 100644 index 0000000..40e8c10 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/crab_claw.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wild_wind_wilderness:item/crab_claw" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/item/fang.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/fang.json new file mode 100644 index 0000000..b6227c7 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/fang.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wild_wind_wilderness:item/fang" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/item/mudcrab_bucket.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/mudcrab_bucket.json new file mode 100644 index 0000000..5591e4e --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/mudcrab_bucket.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wild_wind_wilderness:item/mudcrab_bucket" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/item/mudcrab_spawn_egg.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/mudcrab_spawn_egg.json new file mode 100644 index 0000000..069a63f --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/mudcrab_spawn_egg.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wild_wind_wilderness:item/mudcrab_spawn_egg" + } +} diff --git a/src/hfas/resources/assets/ww_hfas/models/item/omni_claw.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/omni_claw.json similarity index 96% rename from src/hfas/resources/assets/ww_hfas/models/item/omni_claw.json rename to src/wilderness/resources/assets/wild_wind_wilderness/models/item/omni_claw.json index 6c2cb5d..2d19d84 100644 --- a/src/hfas/resources/assets/ww_hfas/models/item/omni_claw.json +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/omni_claw.json @@ -1,8 +1,8 @@ { "texture_size": [32, 32], "textures": { - "2": "ww_hfas:item/omni_claw", - "particle": "ww_hfas:item/omni_claw" + "2": "wild_wind_wilderness:item/omni_claw", + "particle": "wild_wind_wilderness:item/omni_claw" }, "elements": [ { diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/item/piranha.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/piranha.json new file mode 100644 index 0000000..90a120a --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/piranha.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wild_wind_wilderness:item/piranha" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/item/piranha_bucket.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/piranha_bucket.json new file mode 100644 index 0000000..93ceb63 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/piranha_bucket.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wild_wind_wilderness:item/piranha_bucket" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/item/piranha_spawn_egg.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/piranha_spawn_egg.json new file mode 100644 index 0000000..3af630c --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/piranha_spawn_egg.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wild_wind_wilderness:item/piranha_spawn_egg" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/item/soul_boat.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/soul_boat.json new file mode 100644 index 0000000..8877dc1 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/soul_boat.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wild_wind_wilderness:item/soul_boat" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/item/soul_chest_boat.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/soul_chest_boat.json new file mode 100644 index 0000000..a0e3334 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/soul_chest_boat.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wild_wind_wilderness:item/soul_chest_boat" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/item/soul_door.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/soul_door.json new file mode 100644 index 0000000..6728560 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/soul_door.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wild_wind_wilderness:item/soul_door" + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/item/soul_hanging_sign.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/soul_hanging_sign.json new file mode 100644 index 0000000..ce29064 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/soul_hanging_sign.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wild_wind_wilderness:item/soul_hanging_sign" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/item/soul_sapling.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/soul_sapling.json new file mode 100644 index 0000000..9c7be13 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/soul_sapling.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wild_wind_wilderness:block/soul_sapling" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/models/item/soul_sign.json b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/soul_sign.json new file mode 100644 index 0000000..f38d436 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/models/item/soul_sign.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "wild_wind_wilderness:item/soul_sign" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/sounds.json b/src/wilderness/resources/assets/wild_wind_wilderness/sounds.json new file mode 100644 index 0000000..e6a6e17 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/sounds.json @@ -0,0 +1,16 @@ +{ + "entity.piranha.attack": { + "subtitle": "subtitles.entity.piranha.attack", + "sounds": [ + "wild_wind_wilderness:entity_piranha_attack_1", + "wild_wind_wilderness:entity_piranha_attack_2", + "wild_wind_wilderness:entity_piranha_attack_3" + ] + }, + "entity.piranha.death": { + "subtitle": "subtitles.entity.piranha.death", + "sounds": [ + "wild_wind_wilderness:entity_piranha_death" + ] + } +} diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/sounds/entity_piranha_attack_1.ogg b/src/wilderness/resources/assets/wild_wind_wilderness/sounds/entity_piranha_attack_1.ogg new file mode 100644 index 0000000..697e693 Binary files /dev/null and b/src/wilderness/resources/assets/wild_wind_wilderness/sounds/entity_piranha_attack_1.ogg differ diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/sounds/entity_piranha_attack_2.ogg b/src/wilderness/resources/assets/wild_wind_wilderness/sounds/entity_piranha_attack_2.ogg new file mode 100644 index 0000000..3140acb Binary files /dev/null and b/src/wilderness/resources/assets/wild_wind_wilderness/sounds/entity_piranha_attack_2.ogg differ diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/sounds/entity_piranha_attack_3.ogg b/src/wilderness/resources/assets/wild_wind_wilderness/sounds/entity_piranha_attack_3.ogg new file mode 100644 index 0000000..47e7504 Binary files /dev/null and b/src/wilderness/resources/assets/wild_wind_wilderness/sounds/entity_piranha_attack_3.ogg differ diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/sounds/entity_piranha_death.ogg b/src/wilderness/resources/assets/wild_wind_wilderness/sounds/entity_piranha_death.ogg new file mode 100644 index 0000000..ef9bef8 Binary files /dev/null and b/src/wilderness/resources/assets/wild_wind_wilderness/sounds/entity_piranha_death.ogg differ diff --git a/src/hfas/resources/assets/ww_hfas/textures/block/cinder_door_bottom.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/blaze_door_bottom.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/block/cinder_door_bottom.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/block/blaze_door_bottom.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/block/cinder_door_top.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/blaze_door_top.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/block/cinder_door_top.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/block/blaze_door_top.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/block/cinder_leaves.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/blaze_leaves.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/block/cinder_leaves.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/block/blaze_leaves.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/block/cinder_log.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/blaze_log.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/block/cinder_log.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/block/blaze_log.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/block/cinder_log.png.mcmeta b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/blaze_log.png.mcmeta similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/block/cinder_log.png.mcmeta rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/block/blaze_log.png.mcmeta diff --git a/src/hfas/resources/assets/ww_hfas/textures/block/cinder_log_top.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/blaze_log_top.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/block/cinder_log_top.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/block/blaze_log_top.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/block/cinder_log_top.png.mcmeta b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/blaze_log_top.png.mcmeta similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/block/cinder_log_top.png.mcmeta rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/block/blaze_log_top.png.mcmeta diff --git a/src/hfas/resources/assets/ww_hfas/textures/block/cinder_planks.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/blaze_planks.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/block/cinder_planks.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/block/blaze_planks.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/block/cinder_sapling.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/blaze_sapling.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/block/cinder_sapling.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/block/blaze_sapling.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/block/cinder_trapdoor.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/blaze_trapdoor.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/block/cinder_trapdoor.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/block/blaze_trapdoor.png diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/cinder_door_bottom.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/cinder_door_bottom.png new file mode 100644 index 0000000..161d804 Binary files /dev/null and b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/cinder_door_bottom.png differ diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/cinder_door_top.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/cinder_door_top.png new file mode 100644 index 0000000..98b336f Binary files /dev/null and b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/cinder_door_top.png differ diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/cinder_leaves.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/cinder_leaves.png new file mode 100644 index 0000000..e07925b Binary files /dev/null and b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/cinder_leaves.png differ diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/cinder_log.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/cinder_log.png new file mode 100644 index 0000000..7058673 Binary files /dev/null and b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/cinder_log.png differ diff --git a/src/hfas/resources/assets/ww_hfas/textures/block/ember_log.png.mcmeta b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/cinder_log.png.mcmeta similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/block/ember_log.png.mcmeta rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/block/cinder_log.png.mcmeta diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/cinder_log_top.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/cinder_log_top.png new file mode 100644 index 0000000..ee7f2b3 Binary files /dev/null and b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/cinder_log_top.png differ diff --git a/src/hfas/resources/assets/ww_hfas/textures/block/ember_log_top.png.mcmeta b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/cinder_log_top.png.mcmeta similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/block/ember_log_top.png.mcmeta rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/block/cinder_log_top.png.mcmeta diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/cinder_planks.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/cinder_planks.png new file mode 100644 index 0000000..bad9e57 Binary files /dev/null and b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/cinder_planks.png differ diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/cinder_sapling.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/cinder_sapling.png new file mode 100644 index 0000000..b87819d Binary files /dev/null and b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/cinder_sapling.png differ diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/cinder_trapdoor.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/cinder_trapdoor.png new file mode 100644 index 0000000..a28b7ee Binary files /dev/null and b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/cinder_trapdoor.png differ diff --git a/src/hfas/resources/assets/ww_hfas/textures/block/ember_door_bottom.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/ember_door_bottom.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/block/ember_door_bottom.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/block/ember_door_bottom.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/block/ember_door_top.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/ember_door_top.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/block/ember_door_top.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/block/ember_door_top.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/block/ember_leaves.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/ember_leaves.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/block/ember_leaves.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/block/ember_leaves.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/block/ember_log.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/ember_log.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/block/ember_log.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/block/ember_log.png diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/ember_log.png.mcmeta b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/ember_log.png.mcmeta new file mode 100644 index 0000000..67b3e83 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/ember_log.png.mcmeta @@ -0,0 +1,24 @@ +{ + "animation": { + "frametime": 5, + "interpolate": true, + "frames": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15 + ] + } +} \ No newline at end of file diff --git a/src/hfas/resources/assets/ww_hfas/textures/block/ember_log_top.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/ember_log_top.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/block/ember_log_top.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/block/ember_log_top.png diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/ember_log_top.png.mcmeta b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/ember_log_top.png.mcmeta new file mode 100644 index 0000000..67b3e83 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/ember_log_top.png.mcmeta @@ -0,0 +1,24 @@ +{ + "animation": { + "frametime": 5, + "interpolate": true, + "frames": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15 + ] + } +} \ No newline at end of file diff --git a/src/hfas/resources/assets/ww_hfas/textures/block/ember_planks.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/ember_planks.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/block/ember_planks.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/block/ember_planks.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/block/ember_sapling.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/ember_sapling.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/block/ember_sapling.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/block/ember_sapling.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/block/ember_trapdoor.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/ember_trapdoor.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/block/ember_trapdoor.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/block/ember_trapdoor.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/block/scorched_dirt.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/scorched_dirt.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/block/scorched_dirt.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/block/scorched_dirt.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/block/scorched_grass.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/scorched_grass.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/block/scorched_grass.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/block/scorched_grass.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/block/scorched_grass_block_side.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/scorched_grass_block_side.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/block/scorched_grass_block_side.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/block/scorched_grass_block_side.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/block/scorched_grass_block_top.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/scorched_grass_block_top.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/block/scorched_grass_block_top.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/block/scorched_grass_block_top.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/block/scorched_twig.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/scorched_twig.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/block/scorched_twig.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/block/scorched_twig.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/block/scorched_twig_wall.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/scorched_twig_wall.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/block/scorched_twig_wall.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/block/scorched_twig_wall.png diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/soul_door_bottom.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/soul_door_bottom.png new file mode 100644 index 0000000..55cbba2 Binary files /dev/null and b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/soul_door_bottom.png differ diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/soul_door_top.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/soul_door_top.png new file mode 100644 index 0000000..ddd9c8f Binary files /dev/null and b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/soul_door_top.png differ diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/soul_leaves.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/soul_leaves.png new file mode 100644 index 0000000..defa8b1 Binary files /dev/null and b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/soul_leaves.png differ diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/soul_log.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/soul_log.png new file mode 100644 index 0000000..fa20a0d Binary files /dev/null and b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/soul_log.png differ diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/soul_log.png.mcmeta b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/soul_log.png.mcmeta new file mode 100644 index 0000000..67b3e83 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/soul_log.png.mcmeta @@ -0,0 +1,24 @@ +{ + "animation": { + "frametime": 5, + "interpolate": true, + "frames": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15 + ] + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/soul_log_top.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/soul_log_top.png new file mode 100644 index 0000000..2308281 Binary files /dev/null and b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/soul_log_top.png differ diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/soul_log_top.png.mcmeta b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/soul_log_top.png.mcmeta new file mode 100644 index 0000000..67b3e83 --- /dev/null +++ b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/soul_log_top.png.mcmeta @@ -0,0 +1,24 @@ +{ + "animation": { + "frametime": 5, + "interpolate": true, + "frames": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15 + ] + } +} \ No newline at end of file diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/soul_planks.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/soul_planks.png new file mode 100644 index 0000000..8ffdb22 Binary files /dev/null and b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/soul_planks.png differ diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/soul_sapling.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/soul_sapling.png new file mode 100644 index 0000000..831e798 Binary files /dev/null and b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/soul_sapling.png differ diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/soul_trapdoor.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/soul_trapdoor.png new file mode 100644 index 0000000..3c98316 Binary files /dev/null and b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/soul_trapdoor.png differ diff --git a/src/hfas/resources/assets/ww_hfas/textures/block/stripped_cinder_log.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/stripped_blaze_log.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/block/stripped_cinder_log.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/block/stripped_blaze_log.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/block/stripped_cinder_log_top.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/stripped_blaze_log_top.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/block/stripped_cinder_log_top.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/block/stripped_blaze_log_top.png diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/stripped_cinder_log.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/stripped_cinder_log.png new file mode 100644 index 0000000..0700787 Binary files /dev/null and b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/stripped_cinder_log.png differ diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/stripped_cinder_log_top.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/stripped_cinder_log_top.png new file mode 100644 index 0000000..a2f5474 Binary files /dev/null and b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/stripped_cinder_log_top.png differ diff --git a/src/hfas/resources/assets/ww_hfas/textures/block/stripped_ember_log.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/stripped_ember_log.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/block/stripped_ember_log.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/block/stripped_ember_log.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/block/stripped_ember_log_top.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/stripped_ember_log_top.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/block/stripped_ember_log_top.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/block/stripped_ember_log_top.png diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/stripped_soul_log.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/stripped_soul_log.png new file mode 100644 index 0000000..bd1909a Binary files /dev/null and b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/stripped_soul_log.png differ diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/stripped_soul_log_top.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/stripped_soul_log_top.png new file mode 100644 index 0000000..1c6f1a0 Binary files /dev/null and b/src/wilderness/resources/assets/wild_wind_wilderness/textures/block/stripped_soul_log_top.png differ diff --git a/src/hfas/resources/assets/ww_hfas/textures/entity/boat/cinder.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/boat/cinder.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/entity/boat/cinder.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/boat/cinder.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/entity/boat/cinder_boat.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/boat/cinder_boat.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/entity/boat/cinder_boat.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/boat/cinder_boat.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/entity/boat/ember.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/boat/ember.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/entity/boat/ember.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/boat/ember.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/entity/boat/ember_boat.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/boat/ember_boat.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/entity/boat/ember_boat.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/boat/ember_boat.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/entity/chest_boat/cinder.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/chest_boat/cinder.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/entity/chest_boat/cinder.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/chest_boat/cinder.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/entity/chest_boat/cinder_chest_boat.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/chest_boat/cinder_chest_boat.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/entity/chest_boat/cinder_chest_boat.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/chest_boat/cinder_chest_boat.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/entity/chest_boat/ember.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/chest_boat/ember.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/entity/chest_boat/ember.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/chest_boat/ember.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/entity/chest_boat/ember_chest_boat.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/chest_boat/ember_chest_boat.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/entity/chest_boat/ember_chest_boat.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/chest_boat/ember_chest_boat.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/entity/mudcrab/cold.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/mudcrab/cold.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/entity/mudcrab/cold.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/mudcrab/cold.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/entity/mudcrab/temperate.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/mudcrab/temperate.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/entity/mudcrab/temperate.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/mudcrab/temperate.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/entity/mudcrab/warm.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/mudcrab/warm.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/entity/mudcrab/warm.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/mudcrab/warm.png diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/pig/pig_muddy.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/pig/pig_muddy.png new file mode 100644 index 0000000..691b1b1 Binary files /dev/null and b/src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/pig/pig_muddy.png differ diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/pig/pig_muddy_baby.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/pig/pig_muddy_baby.png new file mode 100644 index 0000000..28da447 Binary files /dev/null and b/src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/pig/pig_muddy_baby.png differ diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/piranha.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/piranha.png new file mode 100644 index 0000000..c34e5e6 Binary files /dev/null and b/src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/piranha.png differ diff --git a/src/hfas/resources/assets/ww_hfas/textures/entity/signs/cinder.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/signs/cinder.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/entity/signs/cinder.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/signs/cinder.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/entity/signs/cinder_sign.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/signs/cinder_sign.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/entity/signs/cinder_sign.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/signs/cinder_sign.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/entity/signs/ember.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/signs/ember.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/entity/signs/ember.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/signs/ember.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/entity/signs/ember_sign.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/signs/ember_sign.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/entity/signs/ember_sign.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/signs/ember_sign.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/entity/signs/hanging/cinder.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/signs/hanging/cinder.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/entity/signs/hanging/cinder.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/signs/hanging/cinder.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/entity/signs/hanging/cinder_hanging_sign.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/signs/hanging/cinder_hanging_sign.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/entity/signs/hanging/cinder_hanging_sign.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/signs/hanging/cinder_hanging_sign.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/entity/signs/hanging/ember.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/signs/hanging/ember.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/entity/signs/hanging/ember.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/signs/hanging/ember.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/entity/signs/hanging/ember_hanging_sign.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/signs/hanging/ember_hanging_sign.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/entity/signs/hanging/ember_hanging_sign.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/entity/signs/hanging/ember_hanging_sign.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/gui/hanging_signs/cinder.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/gui/hanging_signs/cinder.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/gui/hanging_signs/cinder.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/gui/hanging_signs/cinder.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/gui/hanging_signs/ember.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/gui/hanging_signs/ember.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/gui/hanging_signs/ember.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/gui/hanging_signs/ember.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/item/cinder_door.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/item/blaze_door.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/item/cinder_door.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/item/blaze_door.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/item/cinder_boat.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/item/cinder_boat.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/item/cinder_boat.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/item/cinder_boat.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/item/cinder_chest_boat.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/item/cinder_chest_boat.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/item/cinder_chest_boat.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/item/cinder_chest_boat.png diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/textures/item/cinder_door.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/item/cinder_door.png new file mode 100644 index 0000000..9191d0b Binary files /dev/null and b/src/wilderness/resources/assets/wild_wind_wilderness/textures/item/cinder_door.png differ diff --git a/src/hfas/resources/assets/ww_hfas/textures/item/cinder_hanging_sign.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/item/cinder_hanging_sign.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/item/cinder_hanging_sign.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/item/cinder_hanging_sign.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/item/cinder_sign.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/item/cinder_sign.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/item/cinder_sign.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/item/cinder_sign.png diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/textures/item/cooked_piranha.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/item/cooked_piranha.png new file mode 100644 index 0000000..fcb0a7f Binary files /dev/null and b/src/wilderness/resources/assets/wild_wind_wilderness/textures/item/cooked_piranha.png differ diff --git a/src/hfas/resources/assets/ww_hfas/textures/item/crab_claw.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/item/crab_claw.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/item/crab_claw.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/item/crab_claw.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/item/ember_boat.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/item/ember_boat.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/item/ember_boat.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/item/ember_boat.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/item/ember_chest_boat.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/item/ember_chest_boat.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/item/ember_chest_boat.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/item/ember_chest_boat.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/item/ember_door.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/item/ember_door.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/item/ember_door.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/item/ember_door.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/item/ember_hanging_sign.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/item/ember_hanging_sign.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/item/ember_hanging_sign.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/item/ember_hanging_sign.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/item/ember_sign.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/item/ember_sign.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/item/ember_sign.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/item/ember_sign.png diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/textures/item/fang.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/item/fang.png new file mode 100644 index 0000000..897b5d9 Binary files /dev/null and b/src/wilderness/resources/assets/wild_wind_wilderness/textures/item/fang.png differ diff --git a/src/hfas/resources/assets/ww_hfas/textures/item/mudcrab_bucket.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/item/mudcrab_bucket.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/item/mudcrab_bucket.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/item/mudcrab_bucket.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/item/mudcrab_spawn_egg.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/item/mudcrab_spawn_egg.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/item/mudcrab_spawn_egg.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/item/mudcrab_spawn_egg.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/item/omni_claw.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/item/omni_claw.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/item/omni_claw.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/item/omni_claw.png diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/textures/item/piranha.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/item/piranha.png new file mode 100644 index 0000000..ea972cf Binary files /dev/null and b/src/wilderness/resources/assets/wild_wind_wilderness/textures/item/piranha.png differ diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/textures/item/piranha_bucket.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/item/piranha_bucket.png new file mode 100644 index 0000000..eee644b Binary files /dev/null and b/src/wilderness/resources/assets/wild_wind_wilderness/textures/item/piranha_bucket.png differ diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/textures/item/piranha_spawn_egg.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/item/piranha_spawn_egg.png new file mode 100644 index 0000000..1748094 Binary files /dev/null and b/src/wilderness/resources/assets/wild_wind_wilderness/textures/item/piranha_spawn_egg.png differ diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/textures/item/soul_door.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/item/soul_door.png new file mode 100644 index 0000000..5cf0c34 Binary files /dev/null and b/src/wilderness/resources/assets/wild_wind_wilderness/textures/item/soul_door.png differ diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/textures/mob_effect/choke.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/mob_effect/choke.png new file mode 100644 index 0000000..af15aca Binary files /dev/null and b/src/wilderness/resources/assets/wild_wind_wilderness/textures/mob_effect/choke.png differ diff --git a/src/wilderness/resources/assets/wild_wind_wilderness/textures/mob_effect/sink.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/mob_effect/sink.png new file mode 100644 index 0000000..58cbce0 Binary files /dev/null and b/src/wilderness/resources/assets/wild_wind_wilderness/textures/mob_effect/sink.png differ diff --git a/src/hfas/resources/assets/ww_hfas/textures/screens/cinder_hanging_sign.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/screens/cinder_hanging_sign.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/screens/cinder_hanging_sign.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/screens/cinder_hanging_sign.png diff --git a/src/hfas/resources/assets/ww_hfas/textures/screens/ember_hanging_sign.png b/src/wilderness/resources/assets/wild_wind_wilderness/textures/screens/ember_hanging_sign.png similarity index 100% rename from src/hfas/resources/assets/ww_hfas/textures/screens/ember_hanging_sign.png rename to src/wilderness/resources/assets/wild_wind_wilderness/textures/screens/ember_hanging_sign.png diff --git a/src/wilderness/resources/data/c/tags/block/fence_gates/wooden.json b/src/wilderness/resources/data/c/tags/block/fence_gates/wooden.json new file mode 100644 index 0000000..475fb54 --- /dev/null +++ b/src/wilderness/resources/data/c/tags/block/fence_gates/wooden.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_fence_gate", + "wild_wind_wilderness:soul_fence_gate" + ] +} diff --git a/src/wilderness/resources/data/c/tags/block/fences.json b/src/wilderness/resources/data/c/tags/block/fences.json new file mode 100644 index 0000000..bb34953 --- /dev/null +++ b/src/wilderness/resources/data/c/tags/block/fences.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_fence", + "wild_wind_wilderness:soul_fence" + ] +} diff --git a/src/wilderness/resources/data/c/tags/block/fences/wooden.json b/src/wilderness/resources/data/c/tags/block/fences/wooden.json new file mode 100644 index 0000000..bb34953 --- /dev/null +++ b/src/wilderness/resources/data/c/tags/block/fences/wooden.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_fence", + "wild_wind_wilderness:soul_fence" + ] +} diff --git a/src/wilderness/resources/data/c/tags/block/stripped_logs.json b/src/wilderness/resources/data/c/tags/block/stripped_logs.json new file mode 100644 index 0000000..06776fb --- /dev/null +++ b/src/wilderness/resources/data/c/tags/block/stripped_logs.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:stripped_blaze_log", + "wild_wind_wilderness:stripped_soul_log" + ] +} diff --git a/src/wilderness/resources/data/c/tags/block/stripped_woods.json b/src/wilderness/resources/data/c/tags/block/stripped_woods.json new file mode 100644 index 0000000..5a2e02a --- /dev/null +++ b/src/wilderness/resources/data/c/tags/block/stripped_woods.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:stripped_blaze_wood", + "wild_wind_wilderness:stripped_soul_wood" + ] +} diff --git a/src/wilderness/resources/data/c/tags/item/animal_foods.json b/src/wilderness/resources/data/c/tags/item/animal_foods.json new file mode 100644 index 0000000..8420663 --- /dev/null +++ b/src/wilderness/resources/data/c/tags/item/animal_foods.json @@ -0,0 +1,5 @@ +{ + "values": [ + "#wild_wind_wilderness:mudcrab_food" + ] +} diff --git a/src/wilderness/resources/data/c/tags/item/fence_gates/wooden.json b/src/wilderness/resources/data/c/tags/item/fence_gates/wooden.json new file mode 100644 index 0000000..475fb54 --- /dev/null +++ b/src/wilderness/resources/data/c/tags/item/fence_gates/wooden.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_fence_gate", + "wild_wind_wilderness:soul_fence_gate" + ] +} diff --git a/src/wilderness/resources/data/c/tags/item/fences/wooden.json b/src/wilderness/resources/data/c/tags/item/fences/wooden.json new file mode 100644 index 0000000..bb34953 --- /dev/null +++ b/src/wilderness/resources/data/c/tags/item/fences/wooden.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_fence", + "wild_wind_wilderness:soul_fence" + ] +} diff --git a/src/wilderness/resources/data/c/tags/item/foods/cooked_fish.json b/src/wilderness/resources/data/c/tags/item/foods/cooked_fish.json new file mode 100644 index 0000000..35113b1 --- /dev/null +++ b/src/wilderness/resources/data/c/tags/item/foods/cooked_fish.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_wilderness:cooked_piranha" + ] +} diff --git a/src/wilderness/resources/data/c/tags/item/stripped_logs.json b/src/wilderness/resources/data/c/tags/item/stripped_logs.json new file mode 100644 index 0000000..06776fb --- /dev/null +++ b/src/wilderness/resources/data/c/tags/item/stripped_logs.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:stripped_blaze_log", + "wild_wind_wilderness:stripped_soul_log" + ] +} diff --git a/src/wilderness/resources/data/c/tags/item/stripped_woods.json b/src/wilderness/resources/data/c/tags/item/stripped_woods.json new file mode 100644 index 0000000..5a2e02a --- /dev/null +++ b/src/wilderness/resources/data/c/tags/item/stripped_woods.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:stripped_blaze_wood", + "wild_wind_wilderness:stripped_soul_wood" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/block/all_hanging_signs.json b/src/wilderness/resources/data/minecraft/tags/block/all_hanging_signs.json new file mode 100644 index 0000000..97c0955 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/block/all_hanging_signs.json @@ -0,0 +1,20 @@ +{ + "values": [ + { + "required": false, + "id": "wild_wind_wilderness:blaze_hanging_sign" + }, + { + "required": false, + "id": "wild_wind_wilderness:blaze_wall_hanging_sign" + }, + { + "required": false, + "id": "wild_wind_wilderness:soul_hanging_sign" + }, + { + "required": false, + "id": "wild_wind_wilderness:soul_wall_hanging_sign" + } + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/block/all_signs.json b/src/wilderness/resources/data/minecraft/tags/block/all_signs.json new file mode 100644 index 0000000..5d234e0 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/block/all_signs.json @@ -0,0 +1,20 @@ +{ + "values": [ + { + "required": false, + "id": "wild_wind_wilderness:blaze_sign" + }, + { + "required": false, + "id": "wild_wind_wilderness:blaze_wall_sign" + }, + { + "required": false, + "id": "wild_wind_wilderness:soul_sign" + }, + { + "required": false, + "id": "wild_wind_wilderness:soul_wall_sign" + } + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/block/dirt.json b/src/wilderness/resources/data/minecraft/tags/block/dirt.json new file mode 100644 index 0000000..8702922 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/block/dirt.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:scorched_grass_block", + "wild_wind_wilderness:scorched_dirt" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/block/doors.json b/src/wilderness/resources/data/minecraft/tags/block/doors.json new file mode 100644 index 0000000..07725a9 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/block/doors.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_door", + "wild_wind_wilderness:soul_door" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/block/fence_gates.json b/src/wilderness/resources/data/minecraft/tags/block/fence_gates.json new file mode 100644 index 0000000..475fb54 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/block/fence_gates.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_fence_gate", + "wild_wind_wilderness:soul_fence_gate" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/block/fences.json b/src/wilderness/resources/data/minecraft/tags/block/fences.json new file mode 100644 index 0000000..bb34953 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/block/fences.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_fence", + "wild_wind_wilderness:soul_fence" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/block/flower_pots.json b/src/wilderness/resources/data/minecraft/tags/block/flower_pots.json new file mode 100644 index 0000000..3c34537 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/block/flower_pots.json @@ -0,0 +1,12 @@ +{ + "values": [ + { + "required": false, + "id": "wild_wind_wilderness:potted_blaze_sapling" + }, + { + "required": false, + "id": "wild_wind_wilderness:potted_soul_sapling" + } + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/block/leaves.json b/src/wilderness/resources/data/minecraft/tags/block/leaves.json new file mode 100644 index 0000000..7d4e464 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/block/leaves.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_leaves", + "wild_wind_wilderness:soul_leaves" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/block/logs.json b/src/wilderness/resources/data/minecraft/tags/block/logs.json new file mode 100644 index 0000000..422d2e7 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/block/logs.json @@ -0,0 +1,12 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_log", + "wild_wind_wilderness:blaze_wood", + "wild_wind_wilderness:stripped_blaze_log", + "wild_wind_wilderness:stripped_blaze_wood", + "wild_wind_wilderness:soul_log", + "wild_wind_wilderness:soul_wood", + "wild_wind_wilderness:stripped_soul_log", + "wild_wind_wilderness:stripped_soul_wood" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/block/logs_that_burn.json b/src/wilderness/resources/data/minecraft/tags/block/logs_that_burn.json new file mode 100644 index 0000000..422d2e7 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/block/logs_that_burn.json @@ -0,0 +1,12 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_log", + "wild_wind_wilderness:blaze_wood", + "wild_wind_wilderness:stripped_blaze_log", + "wild_wind_wilderness:stripped_blaze_wood", + "wild_wind_wilderness:soul_log", + "wild_wind_wilderness:soul_wood", + "wild_wind_wilderness:stripped_soul_log", + "wild_wind_wilderness:stripped_soul_wood" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/block/mineable/axe.json b/src/wilderness/resources/data/minecraft/tags/block/mineable/axe.json new file mode 100644 index 0000000..01330ff --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/block/mineable/axe.json @@ -0,0 +1,30 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_log", + "wild_wind_wilderness:blaze_wood", + "wild_wind_wilderness:stripped_blaze_log", + "wild_wind_wilderness:stripped_blaze_wood", + "wild_wind_wilderness:blaze_planks", + "wild_wind_wilderness:blaze_stairs", + "wild_wind_wilderness:blaze_slab", + "wild_wind_wilderness:blaze_fence", + "wild_wind_wilderness:blaze_fence_gate", + "wild_wind_wilderness:blaze_door", + "wild_wind_wilderness:blaze_trapdoor", + "wild_wind_wilderness:blaze_pressure_plate", + "wild_wind_wilderness:blaze_button", + "wild_wind_wilderness:soul_log", + "wild_wind_wilderness:soul_wood", + "wild_wind_wilderness:stripped_soul_log", + "wild_wind_wilderness:stripped_soul_wood", + "wild_wind_wilderness:soul_planks", + "wild_wind_wilderness:soul_stairs", + "wild_wind_wilderness:soul_slab", + "wild_wind_wilderness:soul_fence", + "wild_wind_wilderness:soul_fence_gate", + "wild_wind_wilderness:soul_door", + "wild_wind_wilderness:soul_trapdoor", + "wild_wind_wilderness:soul_pressure_plate", + "wild_wind_wilderness:soul_button" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/block/needs_stone_tool.json b/src/wilderness/resources/data/minecraft/tags/block/needs_stone_tool.json new file mode 100644 index 0000000..01330ff --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/block/needs_stone_tool.json @@ -0,0 +1,30 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_log", + "wild_wind_wilderness:blaze_wood", + "wild_wind_wilderness:stripped_blaze_log", + "wild_wind_wilderness:stripped_blaze_wood", + "wild_wind_wilderness:blaze_planks", + "wild_wind_wilderness:blaze_stairs", + "wild_wind_wilderness:blaze_slab", + "wild_wind_wilderness:blaze_fence", + "wild_wind_wilderness:blaze_fence_gate", + "wild_wind_wilderness:blaze_door", + "wild_wind_wilderness:blaze_trapdoor", + "wild_wind_wilderness:blaze_pressure_plate", + "wild_wind_wilderness:blaze_button", + "wild_wind_wilderness:soul_log", + "wild_wind_wilderness:soul_wood", + "wild_wind_wilderness:stripped_soul_log", + "wild_wind_wilderness:stripped_soul_wood", + "wild_wind_wilderness:soul_planks", + "wild_wind_wilderness:soul_stairs", + "wild_wind_wilderness:soul_slab", + "wild_wind_wilderness:soul_fence", + "wild_wind_wilderness:soul_fence_gate", + "wild_wind_wilderness:soul_door", + "wild_wind_wilderness:soul_trapdoor", + "wild_wind_wilderness:soul_pressure_plate", + "wild_wind_wilderness:soul_button" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/block/overworld_natural_logs.json b/src/wilderness/resources/data/minecraft/tags/block/overworld_natural_logs.json new file mode 100644 index 0000000..d6fcb9b --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/block/overworld_natural_logs.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_log", + "wild_wind_wilderness:soul_log" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/block/planks.json b/src/wilderness/resources/data/minecraft/tags/block/planks.json new file mode 100644 index 0000000..e890cbf --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/block/planks.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_planks", + "wild_wind_wilderness:soul_planks" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/block/saplings.json b/src/wilderness/resources/data/minecraft/tags/block/saplings.json new file mode 100644 index 0000000..9fb0ce6 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/block/saplings.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_sapling", + "wild_wind_wilderness:soul_sapling" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/block/trapdoors.json b/src/wilderness/resources/data/minecraft/tags/block/trapdoors.json new file mode 100644 index 0000000..f790e39 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/block/trapdoors.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_trapdoor", + "wild_wind_wilderness:soul_trapdoor" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/block/wooden_buttons.json b/src/wilderness/resources/data/minecraft/tags/block/wooden_buttons.json new file mode 100644 index 0000000..b1a8864 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/block/wooden_buttons.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_button", + "wild_wind_wilderness:soul_button" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/block/wooden_doors.json b/src/wilderness/resources/data/minecraft/tags/block/wooden_doors.json new file mode 100644 index 0000000..07725a9 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/block/wooden_doors.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_door", + "wild_wind_wilderness:soul_door" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/block/wooden_fences.json b/src/wilderness/resources/data/minecraft/tags/block/wooden_fences.json new file mode 100644 index 0000000..bb34953 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/block/wooden_fences.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_fence", + "wild_wind_wilderness:soul_fence" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/block/wooden_pressure_plates.json b/src/wilderness/resources/data/minecraft/tags/block/wooden_pressure_plates.json new file mode 100644 index 0000000..d86142b --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/block/wooden_pressure_plates.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_pressure_plate", + "wild_wind_wilderness:soul_pressure_plate" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/block/wooden_slabs.json b/src/wilderness/resources/data/minecraft/tags/block/wooden_slabs.json new file mode 100644 index 0000000..80178e1 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/block/wooden_slabs.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_slab", + "wild_wind_wilderness:soul_slab" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/block/wooden_stairs.json b/src/wilderness/resources/data/minecraft/tags/block/wooden_stairs.json new file mode 100644 index 0000000..e710436 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/block/wooden_stairs.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_stairs", + "wild_wind_wilderness:soul_stairs" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/block/wooden_trapdoors.json b/src/wilderness/resources/data/minecraft/tags/block/wooden_trapdoors.json new file mode 100644 index 0000000..f790e39 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/block/wooden_trapdoors.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_trapdoor", + "wild_wind_wilderness:soul_trapdoor" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/entity_type/aquatic.json b/src/wilderness/resources/data/minecraft/tags/entity_type/aquatic.json new file mode 100644 index 0000000..ad6ed8e --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/entity_type/aquatic.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:mudcrab", + "wild_wind_wilderness:piranha" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/entity_type/arrows.json b/src/wilderness/resources/data/minecraft/tags/entity_type/arrows.json new file mode 100644 index 0000000..2ac5d59 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/entity_type/arrows.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "wild_wind_wilderness:arrow" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/entity_type/axolotl_hunt_targets.json b/src/wilderness/resources/data/minecraft/tags/entity_type/axolotl_hunt_targets.json new file mode 100644 index 0000000..5edca33 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/entity_type/axolotl_hunt_targets.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_wilderness:piranha" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/entity_type/can_breathe_under_water.json b/src/wilderness/resources/data/minecraft/tags/entity_type/can_breathe_under_water.json new file mode 100644 index 0000000..4b64cf8 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/entity_type/can_breathe_under_water.json @@ -0,0 +1,10 @@ +{ + "values": [ + { + "id": "#wild_wind_wilderness:water_breathing", + "required": false + }, + "wild_wind_wilderness:mudcrab", + "wild_wind_wilderness:piranha" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/entity_type/can_equip_saddle.json b/src/wilderness/resources/data/minecraft/tags/entity_type/can_equip_saddle.json new file mode 100644 index 0000000..0d09e46 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/entity_type/can_equip_saddle.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "wild_wind_wilderness:muddy_pig" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/entity_type/not_scary_for_pufferfish.json b/src/wilderness/resources/data/minecraft/tags/entity_type/not_scary_for_pufferfish.json new file mode 100644 index 0000000..ad6ed8e --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/entity_type/not_scary_for_pufferfish.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:mudcrab", + "wild_wind_wilderness:piranha" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/item/arrows.json b/src/wilderness/resources/data/minecraft/tags/item/arrows.json new file mode 100644 index 0000000..305f0da --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/item/arrows.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_wilderness:tipped_arrow" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/item/boats.json b/src/wilderness/resources/data/minecraft/tags/item/boats.json new file mode 100644 index 0000000..b54a307 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/item/boats.json @@ -0,0 +1,12 @@ +{ + "values": [ + { + "required": false, + "id": "wild_wind_wilderness:blaze_boat" + }, + { + "required": false, + "id": "wild_wind_wilderness:soul_boat" + } + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/item/buttons.json b/src/wilderness/resources/data/minecraft/tags/item/buttons.json new file mode 100644 index 0000000..b1a8864 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/item/buttons.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_button", + "wild_wind_wilderness:soul_button" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/item/cat_food.json b/src/wilderness/resources/data/minecraft/tags/item/cat_food.json new file mode 100644 index 0000000..5edca33 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/item/cat_food.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_wilderness:piranha" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/item/chest_boats.json b/src/wilderness/resources/data/minecraft/tags/item/chest_boats.json new file mode 100644 index 0000000..9a56aa9 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/item/chest_boats.json @@ -0,0 +1,12 @@ +{ + "values": [ + { + "required": false, + "id": "wild_wind_wilderness:blaze_chest_boat" + }, + { + "required": false, + "id": "wild_wind_wilderness:soul_chest_boat" + } + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/item/doors.json b/src/wilderness/resources/data/minecraft/tags/item/doors.json new file mode 100644 index 0000000..07725a9 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/item/doors.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_door", + "wild_wind_wilderness:soul_door" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/item/fence_gates.json b/src/wilderness/resources/data/minecraft/tags/item/fence_gates.json new file mode 100644 index 0000000..475fb54 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/item/fence_gates.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_fence_gate", + "wild_wind_wilderness:soul_fence_gate" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/item/fishes.json b/src/wilderness/resources/data/minecraft/tags/item/fishes.json new file mode 100644 index 0000000..9db5509 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/item/fishes.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:piranha", + "wild_wind_wilderness:cooked_piranha" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/item/leaves.json b/src/wilderness/resources/data/minecraft/tags/item/leaves.json new file mode 100644 index 0000000..7d4e464 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/item/leaves.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_leaves", + "wild_wind_wilderness:soul_leaves" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/item/logs.json b/src/wilderness/resources/data/minecraft/tags/item/logs.json new file mode 100644 index 0000000..422d2e7 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/item/logs.json @@ -0,0 +1,12 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_log", + "wild_wind_wilderness:blaze_wood", + "wild_wind_wilderness:stripped_blaze_log", + "wild_wind_wilderness:stripped_blaze_wood", + "wild_wind_wilderness:soul_log", + "wild_wind_wilderness:soul_wood", + "wild_wind_wilderness:stripped_soul_log", + "wild_wind_wilderness:stripped_soul_wood" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/item/logs_that_burn.json b/src/wilderness/resources/data/minecraft/tags/item/logs_that_burn.json new file mode 100644 index 0000000..422d2e7 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/item/logs_that_burn.json @@ -0,0 +1,12 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_log", + "wild_wind_wilderness:blaze_wood", + "wild_wind_wilderness:stripped_blaze_log", + "wild_wind_wilderness:stripped_blaze_wood", + "wild_wind_wilderness:soul_log", + "wild_wind_wilderness:soul_wood", + "wild_wind_wilderness:stripped_soul_log", + "wild_wind_wilderness:stripped_soul_wood" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/item/ocelot_food.json b/src/wilderness/resources/data/minecraft/tags/item/ocelot_food.json new file mode 100644 index 0000000..5edca33 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/item/ocelot_food.json @@ -0,0 +1,5 @@ +{ + "values": [ + "wild_wind_wilderness:piranha" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/item/planks.json b/src/wilderness/resources/data/minecraft/tags/item/planks.json new file mode 100644 index 0000000..e890cbf --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/item/planks.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_planks", + "wild_wind_wilderness:soul_planks" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/item/saplings.json b/src/wilderness/resources/data/minecraft/tags/item/saplings.json new file mode 100644 index 0000000..9fb0ce6 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/item/saplings.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_sapling", + "wild_wind_wilderness:soul_sapling" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/item/trapdoors.json b/src/wilderness/resources/data/minecraft/tags/item/trapdoors.json new file mode 100644 index 0000000..f790e39 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/item/trapdoors.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_trapdoor", + "wild_wind_wilderness:soul_trapdoor" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/item/wolf_food.json b/src/wilderness/resources/data/minecraft/tags/item/wolf_food.json new file mode 100644 index 0000000..9db5509 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/item/wolf_food.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:piranha", + "wild_wind_wilderness:cooked_piranha" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/item/wooden_buttons.json b/src/wilderness/resources/data/minecraft/tags/item/wooden_buttons.json new file mode 100644 index 0000000..b1a8864 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/item/wooden_buttons.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_button", + "wild_wind_wilderness:soul_button" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/item/wooden_doors.json b/src/wilderness/resources/data/minecraft/tags/item/wooden_doors.json new file mode 100644 index 0000000..07725a9 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/item/wooden_doors.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_door", + "wild_wind_wilderness:soul_door" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/item/wooden_fences.json b/src/wilderness/resources/data/minecraft/tags/item/wooden_fences.json new file mode 100644 index 0000000..bb34953 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/item/wooden_fences.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_fence", + "wild_wind_wilderness:soul_fence" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/item/wooden_pressure_plates.json b/src/wilderness/resources/data/minecraft/tags/item/wooden_pressure_plates.json new file mode 100644 index 0000000..d86142b --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/item/wooden_pressure_plates.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_pressure_plate", + "wild_wind_wilderness:soul_pressure_plate" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/item/wooden_slabs.json b/src/wilderness/resources/data/minecraft/tags/item/wooden_slabs.json new file mode 100644 index 0000000..80178e1 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/item/wooden_slabs.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_slab", + "wild_wind_wilderness:soul_slab" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/item/wooden_stairs.json b/src/wilderness/resources/data/minecraft/tags/item/wooden_stairs.json new file mode 100644 index 0000000..e710436 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/item/wooden_stairs.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_stairs", + "wild_wind_wilderness:soul_stairs" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/item/wooden_trapdoors.json b/src/wilderness/resources/data/minecraft/tags/item/wooden_trapdoors.json new file mode 100644 index 0000000..f790e39 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/item/wooden_trapdoors.json @@ -0,0 +1,6 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_trapdoor", + "wild_wind_wilderness:soul_trapdoor" + ] +} diff --git a/src/wilderness/resources/data/minecraft/tags/potion/tradeable.json b/src/wilderness/resources/data/minecraft/tags/potion/tradeable.json new file mode 100644 index 0000000..82f793a --- /dev/null +++ b/src/wilderness/resources/data/minecraft/tags/potion/tradeable.json @@ -0,0 +1,7 @@ +{ + "replace": false, + "values": [ + "wild_wind_wilderness:reach", + "wild_wind_wilderness:long_reach" + ] +} diff --git a/src/wilderness/resources/data/minecraft/wild_wind_wilderness/entity_variant/mudcrab/cold.json b/src/wilderness/resources/data/minecraft/wild_wind_wilderness/entity_variant/mudcrab/cold.json new file mode 100644 index 0000000..5f9af9f --- /dev/null +++ b/src/wilderness/resources/data/minecraft/wild_wind_wilderness/entity_variant/mudcrab/cold.json @@ -0,0 +1,12 @@ +{ + "asset_id": "wild_wind_wilderness:entity/mudcrab/cold", + "spawn_conditions": [ + { + "condition": { + "type": "minecraft:biome", + "biomes": "#wild_wind_wilderness:entity_spawn/mudcrab/cold" + }, + "priority": 1 + } + ] +} diff --git a/src/wilderness/resources/data/minecraft/wild_wind_wilderness/entity_variant/mudcrab/temperate.json b/src/wilderness/resources/data/minecraft/wild_wind_wilderness/entity_variant/mudcrab/temperate.json new file mode 100644 index 0000000..302e094 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/wild_wind_wilderness/entity_variant/mudcrab/temperate.json @@ -0,0 +1,8 @@ +{ + "asset_id": "wild_wind_wilderness:entity/mudcrab/temperate", + "spawn_conditions": [ + { + "priority": 0 + } + ] +} diff --git a/src/wilderness/resources/data/minecraft/wild_wind_wilderness/entity_variant/mudcrab/warm.json b/src/wilderness/resources/data/minecraft/wild_wind_wilderness/entity_variant/mudcrab/warm.json new file mode 100644 index 0000000..d29f835 --- /dev/null +++ b/src/wilderness/resources/data/minecraft/wild_wind_wilderness/entity_variant/mudcrab/warm.json @@ -0,0 +1,12 @@ +{ + "asset_id": "wild_wind_wilderness:entity/mudcrab/warm", + "spawn_conditions": [ + { + "condition": { + "type": "minecraft:biome", + "biomes": "#wild_wind_wilderness:entity_spawn/mudcrab/warm" + }, + "priority": 1 + } + ] +} diff --git a/src/wilderness/resources/data/neoforge/data_maps/block/strippables.json b/src/wilderness/resources/data/neoforge/data_maps/block/strippables.json new file mode 100644 index 0000000..d6d2b7b --- /dev/null +++ b/src/wilderness/resources/data/neoforge/data_maps/block/strippables.json @@ -0,0 +1,16 @@ +{ + "values": { + "wild_wind_wilderness:blaze_log": { + "stripped_block": "wild_wind_wilderness:stripped_blaze_log" + }, + "wild_wind_wilderness:blaze_wood": { + "stripped_block": "wild_wind_wilderness:stripped_blaze_wood" + }, + "wild_wind_wilderness:soul_log": { + "stripped_block": "wild_wind_wilderness:stripped_soul_log" + }, + "wild_wind_wilderness:soul_wood": { + "stripped_block": "wild_wind_wilderness:stripped_soul_wood" + } + } +} diff --git a/src/wilderness/resources/data/wild_wind_core/tags/entity_type/inspection/renewable.json b/src/wilderness/resources/data/wild_wind_core/tags/entity_type/inspection/renewable.json new file mode 100644 index 0000000..0d09e46 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_core/tags/entity_type/inspection/renewable.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "wild_wind_wilderness:muddy_pig" + ] +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/building_blocks/blaze_planks.json b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/building_blocks/blaze_planks.json new file mode 100644 index 0000000..15fca56 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/building_blocks/blaze_planks.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_blaze_log": { + "conditions": { + "items": [ + { + "items": "wild_wind_wilderness:blaze_log" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "wild_wind_wilderness:blaze_planks" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_blaze_log" + ] + ], + "rewards": { + "recipes": [ + "wild_wind_wilderness:blaze_planks" + ] + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/building_blocks/blaze_slab.json b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/building_blocks/blaze_slab.json new file mode 100644 index 0000000..94acc56 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/building_blocks/blaze_slab.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_blaze_planks": { + "conditions": { + "items": [ + { + "items": "wild_wind_wilderness:blaze_planks" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "wild_wind_wilderness:blaze_slab" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_blaze_planks" + ] + ], + "rewards": { + "recipes": [ + "wild_wind_wilderness:blaze_slab" + ] + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/building_blocks/blaze_stairs.json b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/building_blocks/blaze_stairs.json new file mode 100644 index 0000000..ee1649e --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/building_blocks/blaze_stairs.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_blaze_planks": { + "conditions": { + "items": [ + { + "items": "wild_wind_wilderness:blaze_planks" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "wild_wind_wilderness:blaze_stairs" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_blaze_planks" + ] + ], + "rewards": { + "recipes": [ + "wild_wind_wilderness:blaze_stairs" + ] + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/building_blocks/blaze_wood.json b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/building_blocks/blaze_wood.json new file mode 100644 index 0000000..68d990b --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/building_blocks/blaze_wood.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_blaze_log": { + "conditions": { + "items": [ + { + "items": "wild_wind_wilderness:blaze_log" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "wild_wind_wilderness:blaze_wood" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_blaze_log" + ] + ], + "rewards": { + "recipes": [ + "wild_wind_wilderness:blaze_wood" + ] + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/building_blocks/soul_planks.json b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/building_blocks/soul_planks.json new file mode 100644 index 0000000..aff116c --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/building_blocks/soul_planks.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_soul_log": { + "conditions": { + "items": [ + { + "items": "wild_wind_wilderness:soul_log" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "wild_wind_wilderness:soul_planks" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_soul_log" + ] + ], + "rewards": { + "recipes": [ + "wild_wind_wilderness:soul_planks" + ] + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/building_blocks/soul_slab.json b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/building_blocks/soul_slab.json new file mode 100644 index 0000000..59890f2 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/building_blocks/soul_slab.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_soul_planks": { + "conditions": { + "items": [ + { + "items": "wild_wind_wilderness:soul_planks" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "wild_wind_wilderness:soul_slab" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_soul_planks" + ] + ], + "rewards": { + "recipes": [ + "wild_wind_wilderness:soul_slab" + ] + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/building_blocks/soul_stairs.json b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/building_blocks/soul_stairs.json new file mode 100644 index 0000000..27defa3 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/building_blocks/soul_stairs.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_soul_planks": { + "conditions": { + "items": [ + { + "items": "wild_wind_wilderness:soul_planks" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "wild_wind_wilderness:soul_stairs" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_soul_planks" + ] + ], + "rewards": { + "recipes": [ + "wild_wind_wilderness:soul_stairs" + ] + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/building_blocks/soul_wood.json b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/building_blocks/soul_wood.json new file mode 100644 index 0000000..4c0b003 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/building_blocks/soul_wood.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_soul_log": { + "conditions": { + "items": [ + { + "items": "wild_wind_wilderness:soul_log" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "wild_wind_wilderness:soul_wood" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_soul_log" + ] + ], + "rewards": { + "recipes": [ + "wild_wind_wilderness:soul_wood" + ] + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/decorations/blaze_fence.json b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/decorations/blaze_fence.json new file mode 100644 index 0000000..9f70dc3 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/decorations/blaze_fence.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_blaze_planks": { + "conditions": { + "items": [ + { + "items": "wild_wind_wilderness:blaze_planks" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "wild_wind_wilderness:blaze_fence" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_blaze_planks" + ] + ], + "rewards": { + "recipes": [ + "wild_wind_wilderness:blaze_fence" + ] + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/decorations/soul_fence.json b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/decorations/soul_fence.json new file mode 100644 index 0000000..c3a5b2b --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/decorations/soul_fence.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_soul_planks": { + "conditions": { + "items": [ + { + "items": "wild_wind_wilderness:soul_planks" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "wild_wind_wilderness:soul_fence" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_soul_planks" + ] + ], + "rewards": { + "recipes": [ + "wild_wind_wilderness:soul_fence" + ] + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/food/cooked_piranha.json b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/food/cooked_piranha.json new file mode 100644 index 0000000..97a71dd --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/food/cooked_piranha.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_piranha": { + "conditions": { + "items": [ + { + "items": "wild_wind_wilderness:piranha" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "wild_wind_wilderness:cooked_piranha" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_piranha" + ] + ], + "rewards": { + "recipes": [ + "wild_wind_wilderness:cooked_piranha" + ] + } +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/redstone/blaze_button.json b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/redstone/blaze_button.json new file mode 100644 index 0000000..3edf84d --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/redstone/blaze_button.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_blaze_planks": { + "conditions": { + "items": [ + { + "items": "wild_wind_wilderness:blaze_planks" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "wild_wind_wilderness:blaze_button" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_blaze_planks" + ] + ], + "rewards": { + "recipes": [ + "wild_wind_wilderness:blaze_button" + ] + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/redstone/blaze_door.json b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/redstone/blaze_door.json new file mode 100644 index 0000000..9cf26e4 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/redstone/blaze_door.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_blaze_planks": { + "conditions": { + "items": [ + { + "items": "wild_wind_wilderness:blaze_planks" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "wild_wind_wilderness:blaze_door" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_blaze_planks" + ] + ], + "rewards": { + "recipes": [ + "wild_wind_wilderness:blaze_door" + ] + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/redstone/blaze_fence_gate.json b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/redstone/blaze_fence_gate.json new file mode 100644 index 0000000..e6d53f1 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/redstone/blaze_fence_gate.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_blaze_planks": { + "conditions": { + "items": [ + { + "items": "wild_wind_wilderness:blaze_planks" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "wild_wind_wilderness:blaze_fence_gate" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_blaze_planks" + ] + ], + "rewards": { + "recipes": [ + "wild_wind_wilderness:blaze_fence_gate" + ] + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/redstone/blaze_pressure_plate.json b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/redstone/blaze_pressure_plate.json new file mode 100644 index 0000000..dcf19ca --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/redstone/blaze_pressure_plate.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_blaze_planks": { + "conditions": { + "items": [ + { + "items": "wild_wind_wilderness:blaze_planks" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "wild_wind_wilderness:blaze_pressure_plate" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_blaze_planks" + ] + ], + "rewards": { + "recipes": [ + "wild_wind_wilderness:blaze_pressure_plate" + ] + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/redstone/blaze_trapdoor.json b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/redstone/blaze_trapdoor.json new file mode 100644 index 0000000..e65bf97 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/redstone/blaze_trapdoor.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_blaze_planks": { + "conditions": { + "items": [ + { + "items": "wild_wind_wilderness:blaze_planks" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "wild_wind_wilderness:blaze_trapdoor" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_blaze_planks" + ] + ], + "rewards": { + "recipes": [ + "wild_wind_wilderness:blaze_trapdoor" + ] + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/redstone/soul_button.json b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/redstone/soul_button.json new file mode 100644 index 0000000..f061e9d --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/redstone/soul_button.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_soul_planks": { + "conditions": { + "items": [ + { + "items": "wild_wind_wilderness:soul_planks" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "wild_wind_wilderness:soul_button" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_soul_planks" + ] + ], + "rewards": { + "recipes": [ + "wild_wind_wilderness:soul_button" + ] + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/redstone/soul_door.json b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/redstone/soul_door.json new file mode 100644 index 0000000..d8b1dac --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/redstone/soul_door.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_soul_planks": { + "conditions": { + "items": [ + { + "items": "wild_wind_wilderness:soul_planks" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "wild_wind_wilderness:soul_door" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_soul_planks" + ] + ], + "rewards": { + "recipes": [ + "wild_wind_wilderness:soul_door" + ] + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/redstone/soul_fence_gate.json b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/redstone/soul_fence_gate.json new file mode 100644 index 0000000..f733215 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/redstone/soul_fence_gate.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_soul_planks": { + "conditions": { + "items": [ + { + "items": "wild_wind_wilderness:soul_planks" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "wild_wind_wilderness:soul_fence_gate" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_soul_planks" + ] + ], + "rewards": { + "recipes": [ + "wild_wind_wilderness:soul_fence_gate" + ] + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/redstone/soul_pressure_plate.json b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/redstone/soul_pressure_plate.json new file mode 100644 index 0000000..ad71e20 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/redstone/soul_pressure_plate.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_soul_planks": { + "conditions": { + "items": [ + { + "items": "wild_wind_wilderness:soul_planks" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "wild_wind_wilderness:soul_pressure_plate" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_soul_planks" + ] + ], + "rewards": { + "recipes": [ + "wild_wind_wilderness:soul_pressure_plate" + ] + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/redstone/soul_trapdoor.json b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/redstone/soul_trapdoor.json new file mode 100644 index 0000000..72dc773 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/redstone/soul_trapdoor.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_soul_planks": { + "conditions": { + "items": [ + { + "items": "wild_wind_wilderness:soul_planks" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "wild_wind_wilderness:soul_trapdoor" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_soul_planks" + ] + ], + "rewards": { + "recipes": [ + "wild_wind_wilderness:soul_trapdoor" + ] + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/tools/omni_claw.json b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/tools/omni_claw.json new file mode 100644 index 0000000..41759aa --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/advancement/recipes/tools/omni_claw.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_crab_claw": { + "conditions": { + "items": [ + { + "items": "wild_wind_wilderness:omni_claw" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "wild_wind_wilderness:omni_claw" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_crab_claw" + ] + ], + "rewards": { + "recipes": [ + "wild_wind_wilderness:omni_claw" + ] + } +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/blaze_button.json b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/blaze_button.json new file mode 100644 index 0000000..e194b39 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/blaze_button.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_wilderness:blaze_button" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_wilderness:blocks/blaze_button" +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/blaze_door.json b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/blaze_door.json new file mode 100644 index 0000000..69f12e0 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/blaze_door.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "conditions": [ + { + "block": "wild_wind_wilderness:blaze_door", + "condition": "minecraft:block_state_property", + "properties": { + "half": "lower" + } + } + ], + "name": "wild_wind_wilderness:blaze_door" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_wilderness:blocks/blaze_door" +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/blaze_fence.json b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/blaze_fence.json new file mode 100644 index 0000000..04c31e1 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/blaze_fence.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_wilderness:blaze_fence" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_wilderness:blocks/blaze_fence" +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/blaze_fence_gate.json b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/blaze_fence_gate.json new file mode 100644 index 0000000..5d7df3a --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/blaze_fence_gate.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_wilderness:blaze_fence_gate" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_wilderness:blocks/blaze_fence_gate" +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/blaze_leaves.json b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/blaze_leaves.json new file mode 100644 index 0000000..528d646 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/blaze_leaves.json @@ -0,0 +1,130 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "entries": [ + { + "type": "minecraft:alternatives", + "children": [ + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "minecraft:any_of", + "terms": [ + { + "condition": "minecraft:match_tool", + "predicate": { + "items": "minecraft:shears" + } + }, + { + "condition": "minecraft:match_tool", + "predicate": { + "predicates": { + "minecraft:enchantments": [ + { + "enchantments": "minecraft:silk_touch", + "levels": { + "min": 1 + } + } + ] + } + } + } + ] + } + ], + "name": "wild_wind_wilderness:blaze_leaves" + }, + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "minecraft:survives_explosion" + }, + { + "chances": [ + 0.05 + ], + "condition": "minecraft:table_bonus", + "enchantment": "minecraft:fortune" + } + ], + "name": "wild_wind_wilderness:blaze_sapling" + } + ] + } + ], + "rolls": 1.0 + }, + { + "conditions": [ + { + "condition": "minecraft:inverted", + "term": { + "condition": "minecraft:any_of", + "terms": [ + { + "condition": "minecraft:match_tool", + "predicate": { + "items": "minecraft:shears" + } + }, + { + "condition": "minecraft:match_tool", + "predicate": { + "predicates": { + "minecraft:enchantments": [ + { + "enchantments": "minecraft:silk_touch", + "levels": { + "min": 1 + } + } + ] + } + } + } + ] + } + } + ], + "entries": [ + { + "type": "minecraft:item", + "conditions": [ + { + "chances": [ + 0.02, + 0.022222223, + 0.025, + 0.033333335, + 0.1 + ], + "condition": "minecraft:table_bonus", + "enchantment": "minecraft:fortune" + } + ], + "functions": [ + { + "count": { + "type": "minecraft:uniform", + "max": 2.0, + "min": 1.0 + }, + "function": "minecraft:set_count" + }, + { + "function": "minecraft:explosion_decay" + } + ], + "name": "minecraft:stick" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_wilderness:blocks/blaze_leaves" +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/blaze_log.json b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/blaze_log.json new file mode 100644 index 0000000..3ee4f65 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/blaze_log.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_wilderness:blaze_log" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_wilderness:blocks/blaze_log" +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/blaze_planks.json b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/blaze_planks.json new file mode 100644 index 0000000..7ae1e04 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/blaze_planks.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_wilderness:blaze_planks" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_wilderness:blocks/blaze_planks" +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/blaze_pressure_plate.json b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/blaze_pressure_plate.json new file mode 100644 index 0000000..8a1e0e5 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/blaze_pressure_plate.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_wilderness:blaze_pressure_plate" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_wilderness:blocks/blaze_pressure_plate" +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/blaze_sapling.json b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/blaze_sapling.json new file mode 100644 index 0000000..745d181 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/blaze_sapling.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_wilderness:blaze_sapling" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_wilderness:blocks/blaze_sapling" +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/blaze_slab.json b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/blaze_slab.json new file mode 100644 index 0000000..153f864 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/blaze_slab.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_wilderness:blaze_slab" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_wilderness:blocks/blaze_slab" +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/blaze_stairs.json b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/blaze_stairs.json new file mode 100644 index 0000000..85cd619 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/blaze_stairs.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_wilderness:blaze_stairs" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_wilderness:blocks/blaze_stairs" +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/blaze_trapdoor.json b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/blaze_trapdoor.json new file mode 100644 index 0000000..3c9aae7 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/blaze_trapdoor.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_wilderness:blaze_trapdoor" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_wilderness:blocks/blaze_trapdoor" +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/blaze_wood.json b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/blaze_wood.json new file mode 100644 index 0000000..22ccc03 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/blaze_wood.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_wilderness:blaze_wood" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_wilderness:blocks/blaze_wood" +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/scorched_dirt.json b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/scorched_dirt.json new file mode 100644 index 0000000..7b1745e --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/scorched_dirt.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_wilderness:scorched_dirt" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_wilderness:blocks/scorched_dirt" +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/scorched_grass.json b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/scorched_grass.json new file mode 100644 index 0000000..ac263f2 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/scorched_grass.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_wilderness:scorched_grass" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_wilderness:blocks/scorched_grass" +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/scorched_grass_block.json b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/scorched_grass_block.json new file mode 100644 index 0000000..b22ea1c --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/scorched_grass_block.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_wilderness:scorched_grass_block" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_wilderness:blocks/scorched_grass_block" +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/scorched_twig.json b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/scorched_twig.json new file mode 100644 index 0000000..b51fb98 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/scorched_twig.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_wilderness:scorched_twig" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_wilderness:blocks/scorched_twig" +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/soul_button.json b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/soul_button.json new file mode 100644 index 0000000..9e6b315 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/soul_button.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_wilderness:soul_button" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_wilderness:blocks/soul_button" +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/soul_door.json b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/soul_door.json new file mode 100644 index 0000000..8c219bc --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/soul_door.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "conditions": [ + { + "block": "wild_wind_wilderness:soul_door", + "condition": "minecraft:block_state_property", + "properties": { + "half": "lower" + } + } + ], + "name": "wild_wind_wilderness:soul_door" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_wilderness:blocks/soul_door" +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/soul_fence.json b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/soul_fence.json new file mode 100644 index 0000000..3f92064 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/soul_fence.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_wilderness:soul_fence" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_wilderness:blocks/soul_fence" +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/soul_fence_gate.json b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/soul_fence_gate.json new file mode 100644 index 0000000..cfd5fbf --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/soul_fence_gate.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_wilderness:soul_fence_gate" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_wilderness:blocks/soul_fence_gate" +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/soul_leaves.json b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/soul_leaves.json new file mode 100644 index 0000000..98bcfd8 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/soul_leaves.json @@ -0,0 +1,130 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "entries": [ + { + "type": "minecraft:alternatives", + "children": [ + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "minecraft:any_of", + "terms": [ + { + "condition": "minecraft:match_tool", + "predicate": { + "items": "minecraft:shears" + } + }, + { + "condition": "minecraft:match_tool", + "predicate": { + "predicates": { + "minecraft:enchantments": [ + { + "enchantments": "minecraft:silk_touch", + "levels": { + "min": 1 + } + } + ] + } + } + } + ] + } + ], + "name": "wild_wind_wilderness:soul_leaves" + }, + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "minecraft:survives_explosion" + }, + { + "chances": [ + 0.05 + ], + "condition": "minecraft:table_bonus", + "enchantment": "minecraft:fortune" + } + ], + "name": "wild_wind_wilderness:soul_sapling" + } + ] + } + ], + "rolls": 1.0 + }, + { + "conditions": [ + { + "condition": "minecraft:inverted", + "term": { + "condition": "minecraft:any_of", + "terms": [ + { + "condition": "minecraft:match_tool", + "predicate": { + "items": "minecraft:shears" + } + }, + { + "condition": "minecraft:match_tool", + "predicate": { + "predicates": { + "minecraft:enchantments": [ + { + "enchantments": "minecraft:silk_touch", + "levels": { + "min": 1 + } + } + ] + } + } + } + ] + } + } + ], + "entries": [ + { + "type": "minecraft:item", + "conditions": [ + { + "chances": [ + 0.02, + 0.022222223, + 0.025, + 0.033333335, + 0.1 + ], + "condition": "minecraft:table_bonus", + "enchantment": "minecraft:fortune" + } + ], + "functions": [ + { + "count": { + "type": "minecraft:uniform", + "max": 2.0, + "min": 1.0 + }, + "function": "minecraft:set_count" + }, + { + "function": "minecraft:explosion_decay" + } + ], + "name": "minecraft:stick" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_wilderness:blocks/soul_leaves" +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/soul_log.json b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/soul_log.json new file mode 100644 index 0000000..68ea1f3 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/soul_log.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_wilderness:soul_log" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_wilderness:blocks/soul_log" +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/soul_planks.json b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/soul_planks.json new file mode 100644 index 0000000..7f57be1 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/soul_planks.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_wilderness:soul_planks" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_wilderness:blocks/soul_planks" +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/soul_pressure_plate.json b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/soul_pressure_plate.json new file mode 100644 index 0000000..f3ca5d8 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/soul_pressure_plate.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_wilderness:soul_pressure_plate" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_wilderness:blocks/soul_pressure_plate" +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/soul_sapling.json b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/soul_sapling.json new file mode 100644 index 0000000..70554df --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/soul_sapling.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_wilderness:soul_sapling" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_wilderness:blocks/soul_sapling" +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/soul_slab.json b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/soul_slab.json new file mode 100644 index 0000000..c3095c2 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/soul_slab.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_wilderness:soul_slab" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_wilderness:blocks/soul_slab" +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/soul_stairs.json b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/soul_stairs.json new file mode 100644 index 0000000..aa46989 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/soul_stairs.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_wilderness:soul_stairs" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_wilderness:blocks/soul_stairs" +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/soul_trapdoor.json b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/soul_trapdoor.json new file mode 100644 index 0000000..3bbb2df --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/soul_trapdoor.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_wilderness:soul_trapdoor" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_wilderness:blocks/soul_trapdoor" +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/soul_wood.json b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/soul_wood.json new file mode 100644 index 0000000..7962e63 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/soul_wood.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_wilderness:soul_wood" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_wilderness:blocks/soul_wood" +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/stripped_blaze_log.json b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/stripped_blaze_log.json new file mode 100644 index 0000000..dcfc2c0 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/stripped_blaze_log.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_wilderness:stripped_blaze_log" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_wilderness:blocks/stripped_blaze_log" +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/stripped_blaze_wood.json b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/stripped_blaze_wood.json new file mode 100644 index 0000000..2660a14 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/stripped_blaze_wood.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_wilderness:stripped_blaze_wood" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_wilderness:blocks/stripped_blaze_wood" +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/stripped_soul_log.json b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/stripped_soul_log.json new file mode 100644 index 0000000..ec66140 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/stripped_soul_log.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_wilderness:stripped_soul_log" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_wilderness:blocks/stripped_soul_log" +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/stripped_soul_wood.json b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/stripped_soul_wood.json new file mode 100644 index 0000000..98f400c --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/blocks/stripped_soul_wood.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_wilderness:stripped_soul_wood" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_wilderness:blocks/stripped_soul_wood" +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/loot_table/entities/mudcrab.json b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/entities/mudcrab.json new file mode 100644 index 0000000..f81ce12 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/entities/mudcrab.json @@ -0,0 +1,4 @@ +{ + "type": "minecraft:entity", + "random_sequence": "wild_wind_wilderness:entities/mudcrab" +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/loot_table/entities/muddy_pig.json b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/entities/muddy_pig.json new file mode 100644 index 0000000..615a197 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/entities/muddy_pig.json @@ -0,0 +1,14 @@ +{ + "type": "minecraft:entity", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:loot_table", + "value": "minecraft:entities/pig" + } + ] + } + ] +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/loot_table/entities/piranha.json b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/entities/piranha.json new file mode 100644 index 0000000..630d0c6 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/loot_table/entities/piranha.json @@ -0,0 +1,83 @@ +{ + "type": "minecraft:entity", + "pools": [ + { + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "conditions": [ + { + "condition": "minecraft:any_of", + "terms": [ + { + "condition": "minecraft:entity_properties", + "entity": "this", + "predicate": { + "minecraft:flags": { + "is_on_fire": true + } + } + }, + { + "condition": "minecraft:entity_properties", + "entity": "direct_attacker", + "predicate": { + "minecraft:equipment": { + "mainhand": { + "predicates": { + "minecraft:enchantments": [ + { + "enchantments": "#minecraft:smelts_loot" + } + ] + } + } + } + } + } + ] + } + ], + "function": "minecraft:furnace_smelt" + } + ], + "name": "wild_wind_wilderness:piranha" + } + ], + "rolls": 1.0 + }, + { + "conditions": [ + { + "chance": 0.05, + "condition": "minecraft:random_chance" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "minecraft:bone_meal" + } + ], + "rolls": 1.0 + }, + { + "conditions": [ + { + "chance": 0.05, + "condition": "minecraft:random_chance" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "wild_wind_wilderness:fang" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "wild_wind_wilderness:entities/piranha" +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/neoforge/biome_modifier/add_blaze_tree.json b/src/wilderness/resources/data/wild_wind_wilderness/neoforge/biome_modifier/add_blaze_tree.json new file mode 100644 index 0000000..0f75acd --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/neoforge/biome_modifier/add_blaze_tree.json @@ -0,0 +1,6 @@ +{ + "type": "neoforge:add_features", + "biomes": "minecraft:nether_wastes", + "features": "wild_wind_wilderness:blaze_tree_placed", + "step": "vegetal_decoration" +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/neoforge/biome_modifier/add_mudcrab_spawns.json b/src/wilderness/resources/data/wild_wind_wilderness/neoforge/biome_modifier/add_mudcrab_spawns.json new file mode 100644 index 0000000..514f406 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/neoforge/biome_modifier/add_mudcrab_spawns.json @@ -0,0 +1,10 @@ +{ + "type": "neoforge:add_spawns", + "biomes": "#c:is_swamp", + "spawners": { + "type": "wild_wind_wilderness:mudcrab", + "maxCount": 2, + "minCount": 1, + "weight": 1 + } +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/neoforge/biome_modifier/add_muddy_pig.json b/src/wilderness/resources/data/wild_wind_wilderness/neoforge/biome_modifier/add_muddy_pig.json new file mode 100644 index 0000000..30e17c5 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/neoforge/biome_modifier/add_muddy_pig.json @@ -0,0 +1,10 @@ +{ + "type": "neoforge:add_spawns", + "biomes": "#wild_wind_wilderness:spawns_muddy_pig", + "spawners": { + "type": "wild_wind_wilderness:muddy_pig", + "weight": 10, + "minCount": 2, + "maxCount": 4 + } +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/neoforge/biome_modifier/add_piranha_spawns.json b/src/wilderness/resources/data/wild_wind_wilderness/neoforge/biome_modifier/add_piranha_spawns.json new file mode 100644 index 0000000..86b96d7 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/neoforge/biome_modifier/add_piranha_spawns.json @@ -0,0 +1,10 @@ +{ + "type": "neoforge:add_spawns", + "biomes": "#wild_wind_wilderness:entity_spawn/piranha", + "spawners": { + "type": "wild_wind_wilderness:piranha", + "maxCount": 5, + "minCount": 1, + "weight": 8 + } +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/neoforge/biome_modifier/add_soul_tree.json b/src/wilderness/resources/data/wild_wind_wilderness/neoforge/biome_modifier/add_soul_tree.json new file mode 100644 index 0000000..f291060 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/neoforge/biome_modifier/add_soul_tree.json @@ -0,0 +1,6 @@ +{ + "type": "neoforge:add_features", + "biomes": "minecraft:soul_sand_valley", + "features": "wild_wind_wilderness:soul_tree_placed", + "step": "vegetal_decoration" +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/recipe/blaze_button.json b/src/wilderness/resources/data/wild_wind_wilderness/recipe/blaze_button.json new file mode 100644 index 0000000..38c5b8d --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/recipe/blaze_button.json @@ -0,0 +1,10 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "redstone", + "ingredients": [ + "wild_wind_wilderness:blaze_planks" + ], + "result": { + "id": "wild_wind_wilderness:blaze_button" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/recipe/blaze_door.json b/src/wilderness/resources/data/wild_wind_wilderness/recipe/blaze_door.json new file mode 100644 index 0000000..33c2bfe --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/recipe/blaze_door.json @@ -0,0 +1,16 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "redstone", + "key": { + "#": "wild_wind_wilderness:blaze_planks" + }, + "pattern": [ + "##", + "##", + "##" + ], + "result": { + "count": 3, + "id": "wild_wind_wilderness:blaze_door" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/recipe/blaze_fence.json b/src/wilderness/resources/data/wild_wind_wilderness/recipe/blaze_fence.json new file mode 100644 index 0000000..f0d8a11 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/recipe/blaze_fence.json @@ -0,0 +1,15 @@ +{ + "type": "minecraft:crafting_shaped", + "key": { + "#": "minecraft:stick", + "W": "wild_wind_wilderness:blaze_planks" + }, + "pattern": [ + "W#W", + "W#W" + ], + "result": { + "count": 3, + "id": "wild_wind_wilderness:blaze_fence" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/recipe/blaze_fence_gate.json b/src/wilderness/resources/data/wild_wind_wilderness/recipe/blaze_fence_gate.json new file mode 100644 index 0000000..fc73c01 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/recipe/blaze_fence_gate.json @@ -0,0 +1,15 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "redstone", + "key": { + "#": "minecraft:stick", + "W": "wild_wind_wilderness:blaze_planks" + }, + "pattern": [ + "#W#", + "#W#" + ], + "result": { + "id": "wild_wind_wilderness:blaze_fence_gate" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/recipe/blaze_planks.json b/src/wilderness/resources/data/wild_wind_wilderness/recipe/blaze_planks.json new file mode 100644 index 0000000..53e7308 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/recipe/blaze_planks.json @@ -0,0 +1,12 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "planks", + "ingredients": [ + "wild_wind_wilderness:blaze_log" + ], + "result": { + "count": 4, + "id": "wild_wind_wilderness:blaze_planks" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/recipe/blaze_pressure_plate.json b/src/wilderness/resources/data/wild_wind_wilderness/recipe/blaze_pressure_plate.json new file mode 100644 index 0000000..c66d1bc --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/recipe/blaze_pressure_plate.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "redstone", + "key": { + "#": "wild_wind_wilderness:blaze_planks" + }, + "pattern": [ + "##" + ], + "result": { + "id": "wild_wind_wilderness:blaze_pressure_plate" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/recipe/blaze_slab.json b/src/wilderness/resources/data/wild_wind_wilderness/recipe/blaze_slab.json new file mode 100644 index 0000000..c4c15e8 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/recipe/blaze_slab.json @@ -0,0 +1,14 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "key": { + "#": "wild_wind_wilderness:blaze_planks" + }, + "pattern": [ + "###" + ], + "result": { + "count": 6, + "id": "wild_wind_wilderness:blaze_slab" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/recipe/blaze_stairs.json b/src/wilderness/resources/data/wild_wind_wilderness/recipe/blaze_stairs.json new file mode 100644 index 0000000..6af5ece --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/recipe/blaze_stairs.json @@ -0,0 +1,16 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "key": { + "#": "wild_wind_wilderness:blaze_planks" + }, + "pattern": [ + "# ", + "## ", + "###" + ], + "result": { + "count": 4, + "id": "wild_wind_wilderness:blaze_stairs" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/recipe/blaze_trapdoor.json b/src/wilderness/resources/data/wild_wind_wilderness/recipe/blaze_trapdoor.json new file mode 100644 index 0000000..511b0b9 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/recipe/blaze_trapdoor.json @@ -0,0 +1,15 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "redstone", + "key": { + "#": "wild_wind_wilderness:blaze_planks" + }, + "pattern": [ + "###", + "###" + ], + "result": { + "count": 2, + "id": "wild_wind_wilderness:blaze_trapdoor" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/recipe/blaze_wood.json b/src/wilderness/resources/data/wild_wind_wilderness/recipe/blaze_wood.json new file mode 100644 index 0000000..0857e00 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/recipe/blaze_wood.json @@ -0,0 +1,15 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "key": { + "#": "wild_wind_wilderness:blaze_log" + }, + "pattern": [ + "##", + "##" + ], + "result": { + "count": 3, + "id": "wild_wind_wilderness:blaze_wood" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/recipe/cooked_piranha.json b/src/wilderness/resources/data/wild_wind_wilderness/recipe/cooked_piranha.json new file mode 100644 index 0000000..5da591c --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/recipe/cooked_piranha.json @@ -0,0 +1,9 @@ +{ + "type": "minecraft:smelting", + "category": "food", + "experience": 0.35, + "ingredient": "wild_wind_wilderness:piranha", + "result": { + "id": "wild_wind_wilderness:cooked_piranha" + } +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/recipe/omni_claw.json b/src/wilderness/resources/data/wild_wind_wilderness/recipe/omni_claw.json new file mode 100644 index 0000000..9a2be07 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/recipe/omni_claw.json @@ -0,0 +1,16 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "equipment", + "key": { + "C": "wild_wind_wilderness:crab_claw", + "I": "minecraft:copper_ingot" + }, + "pattern": [ + "ICC", + "IIC", + "III" + ], + "result": { + "id": "wild_wind_wilderness:omni_claw" + } +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/recipe/soul_button.json b/src/wilderness/resources/data/wild_wind_wilderness/recipe/soul_button.json new file mode 100644 index 0000000..5c93d25 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/recipe/soul_button.json @@ -0,0 +1,10 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "redstone", + "ingredients": [ + "wild_wind_wilderness:soul_planks" + ], + "result": { + "id": "wild_wind_wilderness:soul_button" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/recipe/soul_door.json b/src/wilderness/resources/data/wild_wind_wilderness/recipe/soul_door.json new file mode 100644 index 0000000..5bc3073 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/recipe/soul_door.json @@ -0,0 +1,16 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "redstone", + "key": { + "#": "wild_wind_wilderness:soul_planks" + }, + "pattern": [ + "##", + "##", + "##" + ], + "result": { + "count": 3, + "id": "wild_wind_wilderness:soul_door" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/recipe/soul_fence.json b/src/wilderness/resources/data/wild_wind_wilderness/recipe/soul_fence.json new file mode 100644 index 0000000..7341c3a --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/recipe/soul_fence.json @@ -0,0 +1,15 @@ +{ + "type": "minecraft:crafting_shaped", + "key": { + "#": "minecraft:stick", + "W": "wild_wind_wilderness:soul_planks" + }, + "pattern": [ + "W#W", + "W#W" + ], + "result": { + "count": 3, + "id": "wild_wind_wilderness:soul_fence" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/recipe/soul_fence_gate.json b/src/wilderness/resources/data/wild_wind_wilderness/recipe/soul_fence_gate.json new file mode 100644 index 0000000..3ccfe88 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/recipe/soul_fence_gate.json @@ -0,0 +1,15 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "redstone", + "key": { + "#": "minecraft:stick", + "W": "wild_wind_wilderness:soul_planks" + }, + "pattern": [ + "#W#", + "#W#" + ], + "result": { + "id": "wild_wind_wilderness:soul_fence_gate" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/recipe/soul_planks.json b/src/wilderness/resources/data/wild_wind_wilderness/recipe/soul_planks.json new file mode 100644 index 0000000..1b4c4b9 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/recipe/soul_planks.json @@ -0,0 +1,12 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "planks", + "ingredients": [ + "wild_wind_wilderness:soul_log" + ], + "result": { + "count": 4, + "id": "wild_wind_wilderness:soul_planks" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/recipe/soul_pressure_plate.json b/src/wilderness/resources/data/wild_wind_wilderness/recipe/soul_pressure_plate.json new file mode 100644 index 0000000..d86a4c1 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/recipe/soul_pressure_plate.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "redstone", + "key": { + "#": "wild_wind_wilderness:soul_planks" + }, + "pattern": [ + "##" + ], + "result": { + "id": "wild_wind_wilderness:soul_pressure_plate" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/recipe/soul_slab.json b/src/wilderness/resources/data/wild_wind_wilderness/recipe/soul_slab.json new file mode 100644 index 0000000..630741d --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/recipe/soul_slab.json @@ -0,0 +1,14 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "key": { + "#": "wild_wind_wilderness:soul_planks" + }, + "pattern": [ + "###" + ], + "result": { + "count": 6, + "id": "wild_wind_wilderness:soul_slab" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/recipe/soul_stairs.json b/src/wilderness/resources/data/wild_wind_wilderness/recipe/soul_stairs.json new file mode 100644 index 0000000..fdbd428 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/recipe/soul_stairs.json @@ -0,0 +1,16 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "key": { + "#": "wild_wind_wilderness:soul_planks" + }, + "pattern": [ + "# ", + "## ", + "###" + ], + "result": { + "count": 4, + "id": "wild_wind_wilderness:soul_stairs" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/recipe/soul_trapdoor.json b/src/wilderness/resources/data/wild_wind_wilderness/recipe/soul_trapdoor.json new file mode 100644 index 0000000..4afea65 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/recipe/soul_trapdoor.json @@ -0,0 +1,15 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "redstone", + "key": { + "#": "wild_wind_wilderness:soul_planks" + }, + "pattern": [ + "###", + "###" + ], + "result": { + "count": 2, + "id": "wild_wind_wilderness:soul_trapdoor" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/recipe/soul_wood.json b/src/wilderness/resources/data/wild_wind_wilderness/recipe/soul_wood.json new file mode 100644 index 0000000..ad9c237 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/recipe/soul_wood.json @@ -0,0 +1,15 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "key": { + "#": "wild_wind_wilderness:soul_log" + }, + "pattern": [ + "##", + "##" + ], + "result": { + "count": 3, + "id": "wild_wind_wilderness:soul_wood" + } +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/tags/block/blaze_logs.json b/src/wilderness/resources/data/wild_wind_wilderness/tags/block/blaze_logs.json new file mode 100644 index 0000000..a94e7ee --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/tags/block/blaze_logs.json @@ -0,0 +1,8 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_log", + "wild_wind_wilderness:blaze_wood", + "wild_wind_wilderness:stripped_blaze_log", + "wild_wind_wilderness:stripped_blaze_wood" + ] +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/tags/block/entity/mudcrab/preferred_wander_blocks.json b/src/wilderness/resources/data/wild_wind_wilderness/tags/block/entity/mudcrab/preferred_wander_blocks.json new file mode 100644 index 0000000..20973c3 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/tags/block/entity/mudcrab/preferred_wander_blocks.json @@ -0,0 +1,7 @@ +{ + "values": [ + "minecraft:mangrove_log", + "minecraft:mangrove_roots", + "minecraft:muddy_mangrove_roots" + ] +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/tags/block/entity/mudcrab/spawnable_in_water_ground.json b/src/wilderness/resources/data/wild_wind_wilderness/tags/block/entity/mudcrab/spawnable_in_water_ground.json new file mode 100644 index 0000000..020b979 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/tags/block/entity/mudcrab/spawnable_in_water_ground.json @@ -0,0 +1,10 @@ +{ + "values": [ + "minecraft:clay", + "minecraft:mud", + "minecraft:dirt", + "minecraft:muddy_mangrove_roots", + "#minecraft:sand", + "#c:gravels" + ] +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/tags/block/entity/mudcrab/spawnable_on.json b/src/wilderness/resources/data/wild_wind_wilderness/tags/block/entity/mudcrab/spawnable_on.json new file mode 100644 index 0000000..d448019 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/tags/block/entity/mudcrab/spawnable_on.json @@ -0,0 +1,6 @@ +{ + "values": [ + "minecraft:mud", + "minecraft:muddy_mangrove_roots" + ] +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/tags/block/muddy_pig_spawnable_on.json b/src/wilderness/resources/data/wild_wind_wilderness/tags/block/muddy_pig_spawnable_on.json new file mode 100644 index 0000000..dbe5311 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/tags/block/muddy_pig_spawnable_on.json @@ -0,0 +1,8 @@ +{ + "replace": false, + "values": [ + "#minecraft:animals_spawnable_on", + "minecraft:mud", + "minecraft:muddy_mangrove_roots" + ] +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/tags/block/soul_logs.json b/src/wilderness/resources/data/wild_wind_wilderness/tags/block/soul_logs.json new file mode 100644 index 0000000..5893cf6 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/tags/block/soul_logs.json @@ -0,0 +1,8 @@ +{ + "values": [ + "wild_wind_wilderness:soul_log", + "wild_wind_wilderness:soul_wood", + "wild_wind_wilderness:stripped_soul_log", + "wild_wind_wilderness:stripped_soul_wood" + ] +} \ No newline at end of file diff --git a/src/wilderness/resources/data/wild_wind_wilderness/tags/entity_type/choke_affected.json b/src/wilderness/resources/data/wild_wind_wilderness/tags/entity_type/choke_affected.json new file mode 100644 index 0000000..6a539d5 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/tags/entity_type/choke_affected.json @@ -0,0 +1,49 @@ +{ + "replace": false, + "values": [ + "minecraft:player", + "minecraft:fox", + "minecraft:camel", + "minecraft:camel_husk", + "minecraft:chicken", + "minecraft:mooshroom", + "minecraft:cow", + "minecraft:donkey", + "minecraft:horse", + "minecraft:mule", + "minecraft:parrot", + "minecraft:pig", + "minecraft:rabbit", + "minecraft:sheep", + "minecraft:sniffer", + "minecraft:turtle", + "minecraft:wandering_trader", + "minecraft:goat", + "minecraft:villager", + "minecraft:cat", + "minecraft:frog", + "minecraft:ocelot", + "minecraft:snow_golem", + "minecraft:bee", + "minecraft:panda", + "minecraft:iron_golem", + "minecraft:llama", + "minecraft:polar_bear", + "minecraft:trader_llama", + "minecraft:wolf", + "minecraft:evoker", + "minecraft:hoglin", + "minecraft:piglin_brute", + "minecraft:pillager", + "minecraft:ravager", + "minecraft:vindicator", + "minecraft:warden", + "minecraft:witch", + "minecraft:creeper", + "minecraft:cave_spider", + "minecraft:spider", + "minecraft:enderman", + "minecraft:piglin", + "wild_wind_wilderness:muddy_pig" + ] +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/tags/entity_type/sink_affected.json b/src/wilderness/resources/data/wild_wind_wilderness/tags/entity_type/sink_affected.json new file mode 100644 index 0000000..7c111af --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/tags/entity_type/sink_affected.json @@ -0,0 +1,47 @@ +{ + "replace": false, + "values": [ + "minecraft:player", + "minecraft:fox", + "minecraft:camel", + "minecraft:camel_husk", + "minecraft:chicken", + "minecraft:mooshroom", + "minecraft:cow", + "minecraft:donkey", + "minecraft:horse", + "minecraft:mule", + "minecraft:parrot", + "minecraft:pig", + "minecraft:rabbit", + "minecraft:sheep", + "minecraft:sniffer", + "minecraft:tadpole", + "minecraft:turtle", + "minecraft:wandering_trader", + "minecraft:goat", + "minecraft:villager", + "minecraft:axolotl", + "minecraft:cat", + "minecraft:frog", + "minecraft:ocelot", + "minecraft:snow_golem", + "minecraft:bee", + "minecraft:panda", + "minecraft:iron_golem", + "minecraft:llama", + "minecraft:polar_bear", + "minecraft:trader_llama", + "minecraft:wolf", + "minecraft:evoker", + "minecraft:hoglin", + "minecraft:piglin_brute", + "minecraft:pillager", + "minecraft:ravager", + "minecraft:vindicator", + "minecraft:warden", + "minecraft:witch", + "minecraft:piglin", + "wild_wind_wilderness:muddy_pig" + ] +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/tags/entity_type/water_breathing.json b/src/wilderness/resources/data/wild_wind_wilderness/tags/entity_type/water_breathing.json new file mode 100644 index 0000000..c21406b --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/tags/entity_type/water_breathing.json @@ -0,0 +1,33 @@ +{ + "replace": false, + "values": [ + "minecraft:cod", + "minecraft:salmon", + "minecraft:tropical_fish", + "minecraft:pufferfish", + "minecraft:squid", + "minecraft:glow_squid", + "minecraft:dolphin", + "minecraft:drowned", + "minecraft:guardian", + "minecraft:elder_guardian", + "minecraft:bogged", + "minecraft:slime", + "minecraft:magma_cube", + "minecraft:zombie", + "minecraft:zombie_villager", + "minecraft:husk", + "minecraft:skeleton", + "minecraft:stray", + "minecraft:wither_skeleton", + "minecraft:zombified_piglin", + "minecraft:zoglin", + "minecraft:phantom", + "minecraft:zombie_horse", + "minecraft:skeleton_horse", + "minecraft:wither", + { "id": "wild_wind_wilderness:mudcrab", "required": false }, + { "id": "wild_wind_core:direfish", "required": false }, + { "id": "wild_wind_wilderness:piranha", "required": false } + ] +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/tags/item/blaze_logs.json b/src/wilderness/resources/data/wild_wind_wilderness/tags/item/blaze_logs.json new file mode 100644 index 0000000..6b5c979 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/tags/item/blaze_logs.json @@ -0,0 +1,8 @@ +{ + "values": [ + "wild_wind_wilderness:blaze_log", + "wild_wind_wilderness:blaze_wood", + "wild_wind_wilderness:stripped_blaze_log", + "wild_wind_wilderness:stripped_blaze_wood" + ] +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/tags/item/mudcrab_food.json b/src/wilderness/resources/data/wild_wind_wilderness/tags/item/mudcrab_food.json new file mode 100644 index 0000000..8e86e0e --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/tags/item/mudcrab_food.json @@ -0,0 +1,5 @@ +{ + "values": [ + "minecraft:spider_eye" + ] +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/tags/item/soul_logs.json b/src/wilderness/resources/data/wild_wind_wilderness/tags/item/soul_logs.json new file mode 100644 index 0000000..bccddb6 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/tags/item/soul_logs.json @@ -0,0 +1,8 @@ +{ + "values": [ + "wild_wind_wilderness:soul_log", + "wild_wind_wilderness:soul_wood", + "wild_wind_wilderness:stripped_soul_log", + "wild_wind_wilderness:stripped_soul_wood" + ] +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/tags/worldgen/biome/entity_spawn/mudcrab/cold.json b/src/wilderness/resources/data/wild_wind_wilderness/tags/worldgen/biome/entity_spawn/mudcrab/cold.json new file mode 100644 index 0000000..6101aab --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/tags/worldgen/biome/entity_spawn/mudcrab/cold.json @@ -0,0 +1,17 @@ +{ + "values": [ + "minecraft:snowy_plains", + "minecraft:ice_spikes", + "minecraft:frozen_peaks", + "minecraft:jagged_peaks", + "minecraft:snowy_slopes", + "minecraft:frozen_ocean", + "minecraft:deep_frozen_ocean", + "minecraft:grove", + "minecraft:deep_dark", + "minecraft:frozen_river", + "minecraft:snowy_taiga", + "minecraft:snowy_beach", + "#minecraft:is_end" + ] +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/tags/worldgen/biome/entity_spawn/mudcrab/warm.json b/src/wilderness/resources/data/wild_wind_wilderness/tags/worldgen/biome/entity_spawn/mudcrab/warm.json new file mode 100644 index 0000000..de055ab --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/tags/worldgen/biome/entity_spawn/mudcrab/warm.json @@ -0,0 +1,11 @@ +{ + "values": [ + "minecraft:desert", + "minecraft:warm_ocean", + "#minecraft:is_jungle", + "#minecraft:is_savanna", + "#minecraft:is_nether", + "#minecraft:is_badlands", + "minecraft:mangrove_swamp" + ] +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/tags/worldgen/biome/entity_spawn/piranha.json b/src/wilderness/resources/data/wild_wind_wilderness/tags/worldgen/biome/entity_spawn/piranha.json new file mode 100644 index 0000000..db9efd8 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/tags/worldgen/biome/entity_spawn/piranha.json @@ -0,0 +1,6 @@ +{ + "values": [ + "minecraft:jungle", + "#c:is_swamp" + ] +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/tags/worldgen/biome/spawns_muddy_pig.json b/src/wilderness/resources/data/wild_wind_wilderness/tags/worldgen/biome/spawns_muddy_pig.json new file mode 100644 index 0000000..7cea7fd --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/tags/worldgen/biome/spawns_muddy_pig.json @@ -0,0 +1,7 @@ +{ + "replace": false, + "values": [ + "minecraft:swamp", + "minecraft:mangrove_swamp" + ] +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/worldgen/configured_feature/blaze_tree.json b/src/wilderness/resources/data/wild_wind_wilderness/worldgen/configured_feature/blaze_tree.json new file mode 100644 index 0000000..3fdb7cc --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/worldgen/configured_feature/blaze_tree.json @@ -0,0 +1,62 @@ +{ + "type": "minecraft:tree", + "config": { + "below_trunk_provider": { + "type": "minecraft:rule_based_state_provider", + "rules": [ + { + "if_true": { + "type": "minecraft:not", + "predicate": { + "type": "minecraft:matching_block_tag", + "tag": "minecraft:cannot_replace_below_tree_trunk" + } + }, + "then": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "minecraft:dirt" + } + } + } + ] + }, + "decorators": [], + "foliage_placer": { + "type": "minecraft:blob_foliage_placer", + "height": 3, + "offset": 0, + "radius": 2 + }, + "foliage_provider": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "wild_wind_wilderness:blaze_leaves", + "Properties": { + "distance": "7", + "persistent": "false", + "waterlogged": "false" + } + } + }, + "ignore_vines": false, + "minimum_size": { + "type": "minecraft:two_layers_feature_size" + }, + "trunk_placer": { + "type": "minecraft:straight_trunk_placer", + "base_height": 4, + "height_rand_a": 2, + "height_rand_b": 0 + }, + "trunk_provider": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "wild_wind_wilderness:blaze_log", + "Properties": { + "axis": "y" + } + } + } + } +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/worldgen/configured_feature/soul_tree.json b/src/wilderness/resources/data/wild_wind_wilderness/worldgen/configured_feature/soul_tree.json new file mode 100644 index 0000000..24fb860 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/worldgen/configured_feature/soul_tree.json @@ -0,0 +1,62 @@ +{ + "type": "minecraft:tree", + "config": { + "below_trunk_provider": { + "type": "minecraft:rule_based_state_provider", + "rules": [ + { + "if_true": { + "type": "minecraft:not", + "predicate": { + "type": "minecraft:matching_block_tag", + "tag": "minecraft:cannot_replace_below_tree_trunk" + } + }, + "then": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "minecraft:dirt" + } + } + } + ] + }, + "decorators": [], + "foliage_placer": { + "type": "minecraft:blob_foliage_placer", + "height": 3, + "offset": 0, + "radius": 2 + }, + "foliage_provider": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "wild_wind_wilderness:soul_leaves", + "Properties": { + "distance": "7", + "persistent": "false", + "waterlogged": "false" + } + } + }, + "ignore_vines": false, + "minimum_size": { + "type": "minecraft:two_layers_feature_size" + }, + "trunk_placer": { + "type": "minecraft:straight_trunk_placer", + "base_height": 4, + "height_rand_a": 2, + "height_rand_b": 0 + }, + "trunk_provider": { + "type": "minecraft:simple_state_provider", + "state": { + "Name": "wild_wind_wilderness:soul_log", + "Properties": { + "axis": "y" + } + } + } + } +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/worldgen/placed_feature/blaze_tree_placed.json b/src/wilderness/resources/data/wild_wind_wilderness/worldgen/placed_feature/blaze_tree_placed.json new file mode 100644 index 0000000..39d4cb1 --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/worldgen/placed_feature/blaze_tree_placed.json @@ -0,0 +1,4 @@ +{ + "feature": "wild_wind_wilderness:blaze_tree", + "placement": [] +} diff --git a/src/wilderness/resources/data/wild_wind_wilderness/worldgen/placed_feature/soul_tree_placed.json b/src/wilderness/resources/data/wild_wind_wilderness/worldgen/placed_feature/soul_tree_placed.json new file mode 100644 index 0000000..bc56f4b --- /dev/null +++ b/src/wilderness/resources/data/wild_wind_wilderness/worldgen/placed_feature/soul_tree_placed.json @@ -0,0 +1,4 @@ +{ + "feature": "wild_wind_wilderness:soul_tree", + "placement": [] +} diff --git a/src/wilderness/resources/wild_wind_wilderness.mixins.json b/src/wilderness/resources/wild_wind_wilderness.mixins.json new file mode 100644 index 0000000..790c023 --- /dev/null +++ b/src/wilderness/resources/wild_wind_wilderness.mixins.json @@ -0,0 +1,27 @@ +{ + "required": true, + "package": "org.polaris2023.wildwind.wilderness.mixin", + "compatibilityLevel": "JAVA_25", + "mixins": [ + "EnchantmentHelperMixin", + "ItemStackMixin", + "MobMixin", + "PlayerMixin", + "ServerPlayerGameModeMixin", + "EntityFluidMovementMixin", + "WaterAnimalAirSupplyMixin", + "IronGolemAirSupplyMixin", + "AbstractArrowAccessor", + "ReachArrowCraftingMixin", + "ReachArrowLootMixin", + "LootPoolEntriesAccessor", + "LootTablePoolsAccessor" + ], + "injectors": { + "defaultRequire": 1 + }, + "overwrites": { + "requireAnnotations": true + }, + "client": [] +} diff --git a/src/wilderness/test/org/polaris2023/wildwind/wilderness/client/MuddyPigModelTest.java b/src/wilderness/test/org/polaris2023/wildwind/wilderness/client/MuddyPigModelTest.java new file mode 100644 index 0000000..b98d700 --- /dev/null +++ b/src/wilderness/test/org/polaris2023/wildwind/wilderness/client/MuddyPigModelTest.java @@ -0,0 +1,60 @@ +package org.polaris2023.wildwind.wilderness.client; + +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.model.animal.pig.PigModel; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.client.model.geom.builders.CubeDeformation; +import net.minecraft.client.renderer.entity.state.PigRenderState; +import org.junit.jupiter.api.Test; +import org.joml.Vector3f; +import static org.junit.jupiter.api.Assertions.*; + +class MuddyPigModelTest { + @Test + void adultAndBabyBakeWithNineAuthoredCubesAndCorrectBounds() { + bounds(MuddyPigModel.adultLayer().bakeRoot(), new float[]{-5, 0, -16, 5, 24, 8}); + bounds(MuddyPigModel.babyLayer().bakeRoot(), new float[]{-4, 10, -8, 3, 24, 5}); + } + + private void bounds(ModelPart root, float[] expected) { + int[] count = {0}; + float[] bounds = {Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, + Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY}; + root.visit(new PoseStack(), (pose, path, index, cube) -> { + count[0]++; + for (float x : new float[]{cube.minX, cube.maxX}) + for (float y : new float[]{cube.minY, cube.maxY}) + for (float z : new float[]{cube.minZ, cube.maxZ}) { + Vector3f v = pose.pose().transformPosition(new Vector3f(x / 16, y / 16, z / 16)).mul(16); + for (int axis = 0; axis < 3; axis++) { + bounds[axis] = Math.min(bounds[axis], v.get(axis)); + bounds[axis + 3] = Math.max(bounds[axis + 3], v.get(axis)); + } + } + }); + assertEquals(9, count[0]); + assertArrayEquals(expected, bounds, 0.0001F); + } + + @Test + void bothAgesUseVanillaPigHeadAndWalkAnimation() { + for (var layer : new net.minecraft.client.model.geom.builders.LayerDefinition[]{ + MuddyPigModel.adultLayer(), MuddyPigModel.babyLayer()}) { + var root = layer.bakeRoot(); + var vanillaRoot = PigModel.createBodyLayer(CubeDeformation.NONE).bakeRoot(); + var muddy = new MuddyPigModel(root); + var vanilla = new PigModel(vanillaRoot); + var state = new PigRenderState(); + state.xRot = 25; + state.yRot = -30; + state.walkAnimationPos = 2.5F; + state.walkAnimationSpeed = 0.7F; + muddy.setupAnim(state); + vanilla.setupAnim(state); + for (String part : new String[]{"head", "right_hind_leg", "left_hind_leg", "right_front_leg", "left_front_leg"}) { + assertEquals(vanillaRoot.getChild(part).xRot, root.getChild(part).xRot); + assertEquals(vanillaRoot.getChild(part).yRot, root.getChild(part).yRot); + } + } + } +}