35 Commits
Author SHA1 Message Date
layue13 b51852c15b ci: ignore docs/reports-only pushes; remove reports/ (GTNHLib#67)
Build / build (push) Successful in 3m6s
Build / publish (push) Successful in 1m35s
2026-11-08 07:40:45 +00:00
layue13 9c7845580b Merge pull request 'perf: a tank looks each neighbour tile up once per tick' (#32) from perf/reuse-block-lookups into main
Build / build (push) Successful in 1m57s
Build / publish (push) Successful in 2m5s
2026-11-07 18:16:40 +00:00
layue13andClaude Sonnet 5.5 3b4bc76cc6 perf: a tank looks each neighbour tile up once per tick
Build / build (push) Skipped
Build / publish (push) Skipped
Build / build (pull_request) Successful in 5m55s
Build / publish (pull_request) Skipped
updateEntity asked the world for the tile above up to three times and the tile
below up to two times per tick; the blocks around cannot change between those
calls (a taint explosion earlier in the tick is handled before the first
lookup), so each is read once. Results identical, pinned by a test that runs
the old lookup sequence next to the new one.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-08 01:59:24 +08:00
layue13 579c7064e2 Merge pull request 'perf: creative node verifies its registration instead of trusting it forever' (#31) from perf/creative-node-self-heal into main
Build / build (push) Successful in 3m31s
Build / publish (push) Successful in 1m59s
2026-11-07 16:02:53 +00:00
layue13andClaude Sonnet 5.5 0ae97629e3 perf: creative node verifies its registration instead of trusting it forever
Build / build (push) Skipped
Build / publish (push) Skipped
Build / build (pull_request) Successful in 2m11s
Build / publish (pull_request) Skipped
#29 registered the location once. The old per-tick rewrite also repaired the shared
TileNode.locations map when another mod cleared or altered it. One lookup and four
int compares per tick restore that: generateId runs again as soon as the entry is
missing or different.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 23:10:59 +08:00
layue13 206d7579ae Merge pull request 'perf: hyper node creator skips redundant aspect rewrites' (#30) from perf/hyper-node-creator into main
Build / build (push) Successful in 54s
Build / publish (push) Successful in 1m5s
2026-11-07 06:20:36 +00:00
layue13andClaude Sonnet 5.5 34f98ad930 perf: hyper node creator rewrites the node only when it no longer holds the wanted aspects
Build / build (push) Skipped
Build / publish (push) Skipped
Build / publish (pull_request) Skipped
Build / build (pull_request) Successful in 43s
Closes TDLM/thaumicadditions#16

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 14:19:39 +08:00
layue13 a0e3d1751f Merge pull request 'perf: creative node registers once, no server stack walk' (#29) from perf/creative-node-registry into main
Build / build (push) Successful in 51s
Build / publish (push) Successful in 45s
2026-11-07 06:18:49 +00:00
layue13andClaude Sonnet 5.5 726fef01f6 perf: creative node registers its location once, server skips the collision stack walk
Build / build (push) Skipped
Build / build (pull_request) Successful in 1m7s
Build / publish (pull_request) Skipped
Build / publish (push) Skipped
Closes TDLM/thaumicadditions#17

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 14:17:27 +08:00
layue13 f523d73954 Merge pull request 'perf: singularity pull box queried once per tick' (#28) from perf/singularity-queries into main
Build / build (push) Successful in 44s
Build / publish (push) Successful in 1m5s
2026-11-07 06:16:34 +00:00
layue13andClaude Sonnet 5.5 51a1e0d83d perf: grounded singularity builds its pull box and queries entities once per tick
Build / build (push) Skipped
Build / publish (push) Skipped
Build / build (pull_request) Successful in 40s
Build / publish (pull_request) Skipped
Closes TDLM/thaumicadditions#21

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 14:15:36 +08:00
layue13 12042a98d8 Merge pull request 'perf: tank and tainted crop lookups hoisted' (#27) from perf/tank-crops-lookups into main
Build / build (push) Successful in 48s
Build / publish (push) Successful in 48s
2026-11-07 06:13:31 +00:00
layue13andClaude Sonnet 5.5 69fc32e3f6 perf: tanks and tainted crops stop re-querying the same positions each tick
Build / build (push) Skipped
Build / publish (push) Skipped
Build / build (pull_request) Successful in 1m25s
Build / publish (pull_request) Skipped
Closes TDLM/thaumicadditions#20, closes TDLM/thaumicadditions#22

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 14:11:48 +08:00
layue13 b8e763aa68 Merge pull request 'guiFactory 指向真实的类' (#26) from fix/guifactory into main
Build / build (push) Successful in 5m39s
Build / publish (push) Successful in 1m40s
2026-11-06 14:47:01 +00:00
layue13andClaude Opus 5.5 0af6cc0b7f 配置界面列出实际分类,补上 Botania 和结构类的旧路径
Build / build (push) Skipped
Build / publish (push) Skipped
Build / build (pull_request) Successful in 5m46s
Build / publish (pull_request) Skipped
配置界面只显示空的 general 分类,选项都在 clientside、customization、misc 里,现在按实际分类列出有选项的分类。
TA.java 里 Botania 的 init、postInit 和 StructureDefiner 的默认类还是 mrdimka 旧路径,改成 com.pengu 下实际存在的类。这几处目标方法都是空的或和原来的回退一样,行为不变。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TiBPbTviTx789GNU9SbE4p
2026-11-06 22:30:58 +08:00
layue13andClaude Opus 5.5 cac303797f guiFactory 指向真实的类
Build / build (push) Skipped
Build / publish (push) Skipped
Build / publish (pull_request) Canceled after 0s
Build / build (pull_request) Canceled after 9m55s
@Mod 里的 guiFactory 还是作者改包名前的 mrdimka 路径,类不存在,启动时报 ClassNotFoundException,模组列表的配置按钮也用不了。
改成 com.pengu 下实际存在的 ConfigurationGuiFactory。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TiBPbTviTx789GNU9SbE4p
2026-11-06 22:20:27 +08:00
layue13 8e0a57d42f Merge pull request 'ci: standard v3 (action upgrades + cache-provider external)' (#25) from ci/standardize-v3 into main
Build / build (push) Successful in 5m30s
Build / publish (push) Successful in 9m11s
2026-11-04 19:08:03 +00:00
layue13 1ea78a02f8 ci: standard v3 (action upgrades + cache-provider external)
Build / build (pull_request) Successful in 1m24s
Build / publish (pull_request) Skipped
Build / build (push) Skipped
Build / publish (push) Skipped
2026-11-04 18:57:49 +00:00
layue13 b82c3fe947 Merge pull request 'ci: apply standard v1 (concurrency + permissions + cache policy)' (#23) from ci/standardize-v1 into main
Build / build (push) Successful in 56m7s
Build / publish (push) Failing after 31m16s
2026-11-04 15:33:10 +00:00
layue13 aa090008cf ci: apply standard v1 (concurrency + permissions + cache policy) 2026-11-04 14:56:26 +00:00
layue13 cded7cd3ee Merge pull request '去掉三个方块缺失贴图的日志报错' (#19) from fix/missing-textures into main
Build / build (push) Successful in 2m17s
Build / publish (push) Successful in 2m41s
2026-11-04 05:54:13 +00:00
layue13andClaude Opus 5.5 737e8d3b28 去掉三个方块缺失贴图的日志报错
infuser_activator、hyper_node_creator、returner_block 都有自己的渲染或不绘制,方块图标只用于粒子。
它们的贴图名指向不存在的文件或根本没设,每次拼贴图都报错。原版 jar 的字节码和资源也是这样,不是反编译造成的。
改指向 jar 里现有的贴图,不加新图。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TiBPbTviTx789GNU9SbE4p
2026-11-04 13:48:14 +08:00
layue13 1b2b9767c9 Merge pull request '去掉物品使用进度条' (#18) from fix/remove-use-bar into main
Build / build (push) Successful in 7m3s
Build / publish (push) Successful in 3m5s
2026-11-04 03:29:26 +00:00
layue13andClaude Opus 5.5 005c58798e 去掉物品使用进度条
吃喝、拉弓、格挡时 HUD 会在屏幕上方画一条进度条,位置用 displayWidth / 8 计算,
不考虑界面缩放,条会偏到左上角。Ethyn 决定不画。
只删这一段,精金护甲条、TipMessage 和 IHUDRenderable 不动。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TiBPbTviTx789GNU9SbE4p
2026-11-04 11:27:31 +08:00
layue13 317a706d97 Merge pull request 'Apply the standard TDLM .gitignore template' (#13) from chore/standard-gitignore into main
Build / build (push) Successful in 10m6s
Build / publish (push) Successful in 12m8s
2026-11-02 15:54:58 +00:00
layue13 f511c38f15 Apply the standard TDLM .gitignore template 2026-11-02 23:46:34 +08:00
layue13 db2028bf13 Merge pull request 'Remove committed runtime artifacts' (#12) from chore/remove-committed-runtime-artifacts into main
Build / build (push) Successful in 4m16s
Build / publish (push) Failing after 3m54s
2026-11-01 18:30:15 +00:00
layue13 cb11c89b5e Remove committed runtime artifacts and ignore them 2026-11-02 01:52:50 +08:00
layue13 6d30f8065b Merge pull request 'perf: watch/boundary items (TESR models reused, single tile lookups, aura packet length check)' (#11) from perf/watch-boundary into main
Build / build (push) Successful in 7m31s
Build / publish (push) Successful in 4m2s
2026-10-31 19:20:02 +00:00
layue13andClaude Opus 5.5 7b7a014a15 docs(reports): close the watch/boundary items fixed or rejected in #11
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-31 21:42:27 +08:00
layue13andClaude Opus 5.5 0fe2dded65 perf: watch/boundary items (TESR models and textures reused, single tile lookups, aura packet length check)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-31 21:41:54 +08:00
layue13 fbc9f7e66f Merge pull request 'build: 发布名改为 thaumicadditions(和整合包一致)' (#10) from build/artifact-name into main
Build / build (push) Successful in 33s
Build / publish (push) Successful in 39s
2026-10-29 08:20:53 +00:00
layue13andClaude Opus 5.5 cfff95a728 build: publish as uk.potatolab:thaumicadditions, the name the pack resolves
Gitea's registry ignored case, so ThaumicAdditions and thaumicadditions were one package there; Nexus is
case-sensitive and the pack (modules.json) asks for thaumicadditions.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-29 16:20:19 +08:00
layue13 b168a9c636 reports: thaumicadditions P2 — F8–F15 sweep, open F-018 (F13 boundary)
- F-018: per-frame text-width re-measure in 9 GUI foreground layers plus
  the HUD TipMessage width loop; boundary with magnitude arithmetic and
  the cache-at-initGui fix path
- exclusion face: F8 guard-in-place (vanilla 64-block TE render cap,
  never overridden), F9/F10/F12/F14 zero form, F11 design body (fixed
  small counts on gameplay events), F15 startup-time icon registration
- F-005 same-shape note (TileRendererCreativeNode), F-016 fix line gains
  its magnitude arithmetic
- hub: HEAD c49b5f0@main, P2 round row, matrix total 18, open 14

[skip ci]
2026-10-29 16:15:12 +08:00
layue13 c49b5f03fb Merge pull request 'build: 升级 Stratum 和依赖到最新的可排序版本' (#9) from build/stratum-bump into main
Build / build (push) Successful in 4m54s
Build / publish (push) Successful in 4m40s
2026-10-29 03:56:16 +00:00
67 changed files with 925 additions and 641 deletions

No files matched your search

+19 -10
View File
@@ -2,7 +2,12 @@ name: Build
on:
push:
branches: [main]
paths-ignore:
- '**.md'
- 'reports/**'
- '.github/ISSUE_TEMPLATE/**'
- '.gitignore'
pull_request:
workflow_dispatch:
inputs:
module-ref:
@@ -18,9 +23,12 @@ on:
required: false
default: 'false'
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: false
cancel-in-progress: ${{ github.ref_name != github.event.repository.default_branch }}
# Organisation-wide Stratum settings (registry, group, runner routes) are organisation variables.
env:
@@ -31,24 +39,25 @@ env:
jobs:
build:
if: github.event_name != 'push' || github.ref_name == github.event.repository.default_branch
runs-on: ubuntu-latest
timeout-minutes: 90
steps:
- uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
ref: ${{ inputs.module-ref || github.sha }}
fetch-depth: 0 # the package version is derived from git history
filter: blob:none
- uses: actions/setup-java@de7274f081f381c8f8158605e0321c36c376e2e6
- uses: actions/setup-java@b843ebf9b913146b38da2eaa7aeddf76074ae1ad
with:
distribution: zulu
java-version: '25'
cache-jdk: true
- uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb
- uses: gradle/actions/setup-gradle@8da46b539cd8fe6ab27ca75128919a18d757604c
with:
cache-provider: basic
cache-provider: "${{ github.server_url == 'https://github.com' && 'basic' || 'external' }}"
- name: Build
env:
@@ -68,21 +77,21 @@ jobs:
MAVEN_USER: ${{ secrets.MAVEN_USER }}
MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }}
steps:
- uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
ref: ${{ inputs.module-ref || github.sha }}
fetch-depth: 0 # the package version is derived from git history
filter: blob:none
- uses: actions/setup-java@de7274f081f381c8f8158605e0321c36c376e2e6
- uses: actions/setup-java@b843ebf9b913146b38da2eaa7aeddf76074ae1ad
with:
distribution: zulu
java-version: '25'
cache-jdk: true
- uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb
- uses: gradle/actions/setup-gradle@8da46b539cd8fe6ab27ca75128919a18d757604c
with:
cache-provider: basic
cache-provider: "${{ github.server_url == 'https://github.com' && 'basic' || 'external' }}"
- name: Check the publish credentials
run: |
+19
View File
@@ -2,3 +2,22 @@ build/
run/
.gradle/
decompile.log
# ==== TDLM standard ignore template ====
# Dev runtime
logs/
*.log
# Build outputs
out/
# Gradle
# IDE
.idea/
*.iml
.vscode/
.classpath
.project
.settings/
eclipse/
# OS
.DS_Store
Thumbs.db
-1
View File
@@ -1 +0,0 @@
ok=307 bad=0 (Fernflower, 逐类反编译)
+1
View File
@@ -4,6 +4,7 @@ repositories {
dependencies {
// Thaumcraft 4 full dev jar (api + common impl; the sources import thaumcraft.common.* and thaumcraft.client.*)
testImplementation("junit:junit:4.13.2")
api("uk.potatolab:Thaumcraft4:4.2.3.5-20261028.155248-g1a600e9")
// cofh.api.energy.IEnergyReceiver is used by TileThaumicGenerator (the CoFH API lives in CoFHLib, not CoFHCore)
compileOnly("uk.potatolab:CoFHLib-1.7.10-Legacy:1.7.10R3.0.3-20261028.145717-gbf0ac89")
-22
View File
@@ -1,22 +0,0 @@
# F-001
- **状态**:修·已修复(会话合入 TDLM/thaumicadditions#4,2026-10-26)
- **范式**:B1
- **位置**:`.github/workflows/build.yml:3-5`、`:55`
- **证据**:
```yaml
on:
push:
branches: [main]
```
(`.github/workflows/build.yml:3-5`;全文件无 `concurrency:` 键)
```yaml
if: ${{ github.event_name == 'push' || inputs.publish == 'true' }}
```
(`:55`;`:24`/`:57` `timeout-minutes` 在位)
- **机制**:workflow 无 concurrency 组而 push 即进入 publish job,连续 push 并行构建并争发构件。
- **频率**:每次 push(CI 期)。
- **修法**:补 `concurrency: { group: ${{ github.workflow }}-${{ github.ref }}, cancel-in-progress: false }`(含发布步骤,取 false 保逐 commit 构件)。
- **风险 · 置信度**:无(仅消并发发布竞争) · 高
- **移交**:无
- **来源**:P1 2026-10-26 2f7b9c9
- **修复**:会话合入 TDLM/thaumicadditions#4,2026-10-26。
-19
View File
@@ -1,19 +0,0 @@
# F-002
- **状态**:修·已修复(会话合入 TDLM/thaumicadditions#4,2026-10-26)
- **范式**:B1
- **位置**:`build.gradle:19-28`
- **证据**:
```gradle
repositories {
maven {
name = 'TDLM Maven'
url = 'https://git.nest.potatolab.uk:8443/api/packages/TDLM/maven'
```
(`build.gradle:18-21`;块内无 `content { includeGroup … }`;对照 `settings.gradle:6-8` GTNH 块有 mavenContent 正例)
- **机制**:自建 TDLM maven 无 content 过滤,依赖解析对无关坐标反复探测 404。
- **频率**:每次依赖解析(构建期)。
- **修法**:maven 块补 `content { includeGroup("uk.potatolab") }`(或本仓实际 group 集合)。
- **风险 · 置信度**:无 · 高
- **移交**:无
- **来源**:P1 2026-10-26 2f7b9c9
- **修复**:会话合入 TDLM/thaumicadditions#4,2026-10-26。
-16
View File
@@ -1,16 +0,0 @@
# F-003
- **状态**:修·已修复(会话合入 TDLM/thaumicadditions#4,2026-10-26)
- **范式**:T4
- **位置**:`src/main/java/com/pengu/thaumcraft/additions/tileentity/TileVoidChest.java:55`
- **证据**:
```java
public void updateEntity() {}
```
(`:55`;全仓 `boolean canUpdate(` 覆写 0;1.7.10 `TileEntity.canUpdate()` 默认 true;注册见 `init/MTE.java:37`)
- **机制**:虚空箱有空体 updateEntity 且未关 tick 资格,世界内每箱每 tick 白付调度。
- **频率**:每 tick × 每虚空箱实例。
- **修法**:覆写 `canUpdate()` 返回 false(空体无副作用,零行为变更)。
- **风险 · 置信度**:无 · 高
- **移交**:无
- **来源**:P1 2026-10-26 2f7b9c9;同族 F-004
- **修复**:会话合入 TDLM/thaumicadditions#4,2026-10-26。
-16
View File
@@ -1,16 +0,0 @@
# F-004
- **状态**:修·已修复(会话合入 TDLM/thaumicadditions#4,2026-10-26)
- **范式**:T4
- **位置**:`src/main/java/com/pengu/thaumcraft/additions/tileentity/TileReturner.java:6`
- **证据**:
```java
public class TileReturner extends TileEntity {
```
(`:6`;类内无 `updateEntity`/`canUpdate`;`BlockReturner.java:22` `TileEntity.addMapping(TileReturner.class, …)`)
- **机制**:返回器仅存坐标 NBT,继承基类空 updateEntity,默认 canUpdate=true 仍进 tick 表。
- **频率**:每 tick × 每返回器。
- **修法**:覆写 `canUpdate()` 返回 false。
- **风险 · 置信度**:无 · 高
- **移交**:无
- **来源**:P1 2026-10-26 2f7b9c9;同族 F-003
- **修复**:会话合入 TDLM/thaumicadditions#4,2026-10-26。
-19
View File
@@ -1,19 +0,0 @@
# F-005
- **状态**:观察·待处理
- **范式**:F1
- **位置**:`src/main/java/com/pengu/thaumcraft/additions/renderer/RendererDarkGen.java:16`、`:22`;同型 `RendererHyperNodeCreator.java:17`、`:23`、`RendererInfuser.java:19`、`:24`、`RendererInfuserActivator.java:19`、`:37`、`RendererSymboller.java:17`、`:23`、`RendererThaumicGenerator.java:17`、`:23`、`RendererThaumicRestorer.java:16`、`:22`、`RendererSeal.java:41-48`、`RendererTankBasic.java:20`、`:32`
- **证据**:
```java
ResourceLocation textures = new ResourceLocation("thaumicadditions", "textures/models/DarkGen.png");
```
(RendererDarkGen.java:16)
```java
(new ModelDarkGen()).render((Entity)null, 0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F, false);
```
(`:22`;Seal 同帧多次 `new ModelSeal()` 见 RendererSeal.java:42/:48/:61/:72/:83)
- **机制**:多枚 TESR 每帧重建不可变 ResourceLocation 与 Model 实例;路径常量可 static final,Model 可字段复用。
- **频率**:每帧 × 可视 TESR 实例。
- **修法**:提 `private static final ResourceLocation`;Model 提实例字段复用(需确认无跨 TE 可变状态串扰,故本档观察)。
- **风险 · 置信度**:RL 提常量无;Model 复用需隔离论证 · 高(形态)
- **移交**:无
- **来源**:P1 2026-10-26 2f7b9c9;同族 F-006/F-016
-20
View File
@@ -1,20 +0,0 @@
# F-006
- **状态**:观察·待处理
- **范式**:F1
- **位置**:`src/main/java/com/pengu/thaumcraft/additions/tileentity/TileRendererCreativeNode.java:22-23`、`:34`
- **证据**:
```java
Random rnd = new Random((long)(tcn.getId() + "" + tcn.yCoord).hashCode() ^ 256L);
float rot = (float)(Calendar.getInstance().get(14) + rnd.nextInt(1000)) % 1000.0F;
```
(`:22-23`)
```java
Minecraft.getMinecraft().getTextureManager().bindTexture(new ResourceLocation("thaumicadditions", "textures/models/aura_" + (rnd.nextInt(2) + 1) + ".png"));
```
(`:34`)
- **机制**:创造节点 TESR 每帧 new Random、Calendar.getInstance、拼接 ResourceLocation;固定种子序列可预计算。
- **频率**:每帧 × 可视创造节点。
- **修法**:种子 Random/两张 aura RL 提字段;时间改 `System.currentTimeMillis()%1000` 或字段时钟。量级未证 ⇒ 观察。
- **风险 · 置信度**:低(动画相位需对齐) · 高(形态)
- **移交**:无
- **来源**:P1 2026-10-26 2f7b9c9;同族 F-005
-18
View File
@@ -1,18 +0,0 @@
# F-007
- **状态**:观察·待处理
- **范式**:S1
- **位置**:`src/main/java/com/pengu/thaumcraft/additions/entity/EntitySingularity.java:70-73`
- **证据**:
```java
for(p = 0; p < 128; ++p) {
AxisAlignedBB ent = AxisAlignedBB.getBoundingBox(this.posX - (double)this.radius, this.posY - (double)this.radius, this.posZ - (double)this.radius, this.posX + (double)this.radius, this.posY + (double)this.radius, this.posZ + (double)this.radius);
l = this.worldObj.getEntitiesWithinAABB(Entity.class, ent);
l2 = this.worldObj.getEntitiesWithinAABB(EntityLivingBase.class, ent);
```
(`:70-73`;`radius = 10` 见 `:22`;落地分支 `:56`)
- **机制**:奇点落地后每 tick 将同一 21³ 盒 AABB 查询重复 128 次×两类实体,盒有界但频率无 interval,乘子为设计放大。
- **频率**:每 tick × 每落地奇点 × 256 次查询(静态推断)。
- **修法**:单次双查询后在循环内处理;或降循环次数。行为/手感可能变 ⇒ 观察,量级需 profile。
- **风险 · 置信度**:中(牵引力/破坏节奏) · 高(形态)
- **移交**:无
- **来源**:P1 2026-10-26 2f7b9c9
-16
View File
@@ -1,16 +0,0 @@
# F-008
- **状态**:观察·待处理
- **范式**:S1
- **位置**:`src/main/java/com/pengu/thaumcraft/additions/event/sealing/SealEventCollectItems.java:25-26`
- **证据**:
```java
AxisAlignedBB aabb = AxisAlignedBB.getBoundingBox((double)(x - 16), (double)(y - 16), (double)(z - 16), (double)(x + 16), (double)(y + 16), (double)(z + 16));
List i = world.getEntitiesWithinAABB(EntityItem.class, aabb);
```
(`:25-26`;由 `TileSeal.updateEntity` `:62` 每 tick 调用)
- **机制**:收集印激活时每 tick 扫 33³ 盒掉落物,有半径无 interval/短路门。
- **频率**:每 tick × 每匹配收集印。
- **修法**:加 interval 或相位门;缩小盒需平衡裁决。量级未证 ⇒ 观察。
- **风险 · 置信度**:中(收集半径即玩法) · 高(形态)
- **移交**:无
- **来源**:P1 2026-10-26 2f7b9c9
-19
View File
@@ -1,19 +0,0 @@
# F-009
- **状态**:观察·待处理
- **范式**:T1
- **位置**:`src/main/java/com/pengu/thaumcraft/additions/tileentity/TileInfuser.java:41-45`;`TileDarkInfuser.java:41-45`
- **证据**:
```java
List var5 = InfuserRecipeRegistry.complexOfRecipes.recipesOnTheRegularInfuser;
int foundRecipes = 0;
for(int i = 0; i < var5.size(); ++i) {
if(areItemStacksEqual(this.slots[1], ((InfuserRecipe)var5.get(i)).input1) && areItemStacksEqual(this.slots[2], ((InfuserRecipe)var5.get(i)).input2) && areItemStacksEqual(this.slots[3], ((InfuserRecipe)var5.get(i)).input3) && areItemStacksEqual(this.slots[4], ((InfuserRecipe)var5.get(i)).input4) && areItemStacksEqual(this.slots[5], ((InfuserRecipe)var5.get(i)).input5) && areItemStacksEqual(this.slots[6], ((InfuserRecipe)var5.get(i)).input6) && (this.slots[0] == null || areItemStacksEqual(this.slots[0], ((InfuserRecipe)var5.get(i)).output) && this.slots[0].stackSize + ((InfuserRecipe)var5.get(i)).output.stackSize < this.slots[0].getMaxStackSize())) {
```
(TileInfuser.java:41-45;Dark 表同型 `:41-45`;注册约 7+4 条见 `init/MIR.java`)
- **机制**:注能/暗注能每 tick 无缓存全表线性匹配六格输入;表近静态。
- **频率**:每 tick × 每台注能器。
- **修法**:槽位指纹缓存命中配方下标,槽变更失效。表小量级未证 ⇒ 观察。
- **风险 · 置信度**:低 · 高(形态)
- **移交**:无
- **来源**:P1 2026-10-26 2f7b9c9
-15
View File
@@ -1,15 +0,0 @@
# F-010
- **状态**:观察·待处理
- **范式**:T1
- **位置**:`src/main/java/com/pengu/thaumcraft/additions/tileentity/TileTileBooster.java:27`
- **证据**:
```java
TileEntity te = this.worldObj.getTileEntity(x, y, z) != null && !(this.worldObj.getTileEntity(x, y, z) instanceof TileTileBooster)?this.worldObj.getTileEntity(x, y, z):null;
```
(`:27`;六向循环 `:22-33`)
- **机制**:加速器每 tick 每向对同坐标最多三次 getTileEntity。
- **频率**:每 tick × 6 向 × 每加速器。
- **修法**:`TileEntity te = worldObj.getTileEntity(x,y,z)` 提局部一次。零行为;量级随实例未证 ⇒ 观察。
- **风险 · 置信度**:无 · 高
- **移交**:无
- **来源**:P1 2026-10-26 2f7b9c9;同族 F-011/F-013
-15
View File
@@ -1,15 +0,0 @@
# F-011
- **状态**:观察·待处理
- **范式**:T1
- **位置**:`src/main/java/com/pengu/thaumcraft/additions/tileentity/TileThaumicGenerator.java:62-87`、`:71`
- **证据**:
```java
if(Loader.isModLoaded("Botania") && (new Botania()).canConnect(this.worldObj, this.xCoord, this.yCoord, this.zCoord, dirs[i])) {
```
(`:71`;同方法 `:62-82` 多处重复 `getTileEntity(...)`;`:85-86` 再次 `Loader.isModLoaded` + `new Botania()`)
- **机制**:发电机有能量时每 tick 六向重复 TE 查找,并反复 `Loader.isModLoaded` 与 `new Botania()`。
- **频率**:每 tick × 有能量的发电机 × 6 向。
- **修法**:`isModLoaded` 提 static final;Botania 桥接单例;getTileEntity 提局部。量级未证 ⇒ 观察。
- **风险 · 置信度**:低 · 高(形态)
- **移交**:无
- **来源**:P1 2026-10-26 2f7b9c9;同族 F-010
-24
View File
@@ -1,24 +0,0 @@
# F-012
- **状态**:观察·待处理
- **范式**:T1
- **位置**:`src/main/java/com/pengu/thaumcraft/additions/tileentity/TileSeal.java:43`、`:57-62`
- **证据**:
```java
this.current = new SealCombo(new Seal[]{this.f});
```
(`:43`)
```java
List events = MSE.events.eventList;
for(int i = 0; i < events.size(); ++i) {
if(this.CompareSealCombos(this.f, ((SealEvent)events.get(i)).getSealCombination().getSeal1()) && this.CompareSealCombos(this.s, ((SealEvent)events.get(i)).getSealCombination().getSeal2()) && this.CompareSealCombos(this.t, ((SealEvent)events.get(i)).getSealCombination().getSeal3()) || this.current.length() == 3 && ((SealEvent)events.get(i)).getSealCombination().length() == 2 && ((SealEvent)events.get(i)).canWorkWith3rdSymbol(this.t)) {
SealEvent event = (SealEvent)events.get(i);
event.sealTick(this.worldObj, this.xCoord, this.yCoord, this.zCoord, this.f, this.s, this.t, this.extraNBT);
```
(`:57-62`)
- **机制**:封印每 tick 新建 SealCombo 并对近静态事件表线性匹配;印面未变时结果可记忆。
- **频率**:每 tick × 每封印方块。
- **修法**:印面指纹缓存 `currentWorkingComboID`,变更再全表扫。缓存语义需核对 ⇒ 观察。
- **风险 · 置信度**:低 · 中
- **移交**:无
- **来源**:P1 2026-10-26 2f7b9c9
-16
View File
@@ -1,16 +0,0 @@
# F-013
- **状态**:观察·待处理
- **范式**:T1
- **位置**:`src/main/java/com/pengu/thaumcraft/additions/piping/TileVisTube.java:61-75`、`:98`
- **证据**:
```java
if(this.worldObj.getTileEntity(x, y, z) instanceof ITubeConnectable) {
ITubeConnectable tube = (ITubeConnectable)this.worldObj.getTileEntity(x, y, z);
```
(`:61-62`;`:74-75` 同坐标再查 `ITubable`;`:98` 合并环再双查)
- **机制**:灵气管每 tick 六向对同坐标多次 getTileEntity 做连通与合并。
- **频率**:每 tick × 每管段 × 至多两轮六向。
- **修法**:每向 `TileEntity te = getTileEntity(...)` 一次后分支。零行为;管网密度未证 ⇒ 观察。
- **风险 · 置信度**:无 · 高
- **移交**:无
- **来源**:P1 2026-10-26 2f7b9c9;同族 F-010
-19
View File
@@ -1,19 +0,0 @@
# F-014
- **状态**:边界·待处理
- **范式**:N1
- **位置**:`src/main/java/com/pengu/thaumcraft/additions/playnet/packtetmng/PacketAuraVis.java:38`、`:45`
- **证据**:
```java
this.amts = new int[buf.readInt()];
```
(`:38`)
```java
this.aspects = new EnumAT[buf.readInt()];
```
(`:45`;分配后无 clamp)
- **机制**:两处数组长度直取网络 int,无上限;畸形包可驱动大分配。
- **频率**:每入站包。
- **修法**:记录不修(边界):协议本为短枚举列表;上限取值需安全侧/包维护者裁决。建议 clamp 至 `EnumAT` 基数后超限断连。
- **风险 · 置信度**:安全相邻 · 高(形态)
- **移交**:安全侧
- **来源**:P1 2026-10-26 2f7b9c9
-15
View File
@@ -1,15 +0,0 @@
# F-015
- **状态**:边界·待处理
- **范式**:T15
- **位置**:`src/main/java/com/pengu/thaumcraft/additions/tileentity/TileTankBasic.java:45`
- **证据**:
```java
boolean ttb = rand.nextInt(1000) < 100 && ext > 0.5F;
```
(`:45`;`:43` `!isRemote` 门内每 tick)
- **机制**:污秽过半时每 tick 重掷约 10% 爆炸门,事件稀疏却抽样= tick×实例。
- **频率**:每 tick × 高污秽储罐。
- **修法**:记录不修:分布改倒计时会变爆炸时序;量级在污秽门后。若修则预约下次爆炸 tick。
- **风险 · 置信度**:中(时序) · 高(形态)
- **移交**:无
- **来源**:P1 2026-10-26 2f7b9c9
-15
View File
@@ -1,15 +0,0 @@
# F-016
- **状态**:边界·待处理
- **范式**:F1
- **位置**:`src/main/java/com/pengu/thaumcraft/additions/gui/GUIInfuser.java:24`;同型 `GUICondensator.java:26`、`GUIDarkGenerator.java:26`、`GUIDarkInfuser.java:26`、`GUIHyperNodeCreator.java:25`、`GUISealGlobe.java:38`、`GUIThaumicCrystallizer.java:24`、`GUIThaumicGenerator.java:24`、`GUIThaumicRestorer.java:25`、`GUIVoidChest.java:23`
- **证据**:
```java
Minecraft.getMinecraft().getTextureManager().bindTexture(new ResourceLocation("thaumicadditions", "textures/gui/guiinfuser.png"));
```
(GUIInfuser.java:24;其余 9 处同句式换路径)
- **机制**:十个容器 GUI 背景层每帧 new ResourceLocation;可提 static final。
- **频率**:每帧(GUI 打开期间)。
- **修法**:记录不修:形态命中量级微(仅开 GUI);维护者可按 TESR 同法提常量。
- **风险 · 置信度**:无 · 高
- **移交**:无
- **来源**:P1 2026-10-26 2f7b9c9;同族 F-005
-15
View File
@@ -1,15 +0,0 @@
# F-017
- **状态**:观察·待处理
- **范式**:D1
- **位置**:`src/main/java/com/pengu/thaumcraft/additions/playnet/packtetmng/PacketAuraVis.java:25`
- **证据**:
```java
FMLLog.info("Received!", new Object[0]);
```
(`:25`;`onMessage` 内、try 块首行)
- **机制**:灵气同步包每包打 INFO,控制台同步 IO 随包频放大。
- **频率**:每包(客户端收包沿)。
- **修法**:删除该行或改 `FMLLog.fine`/debug 开关。若运维依赖该日志则裁决。
- **风险 · 置信度**:低(可观测性) · 高
- **移交**:无
- **来源**:P1 2026-10-26 2f7b9c9;同点位 F-014
-120
View File
@@ -1,120 +0,0 @@
# thaumicadditions — reports
本目录为该模组 F-item 的**权威来源**(自 TDLMPack `reports/repos/` 迁入)。
## 索引
| ID | 状态 | 文件 |
|---|---|---|
| [F-001](F-001.md) | 修·已修复 | `F-001.md` |
| [F-002](F-002.md) | 修·已修复 | `F-002.md` |
| [F-003](F-003.md) | 修·已修复 | `F-003.md` |
| [F-004](F-004.md) | 修·已修复 | `F-004.md` |
| [F-005](F-005.md) | 观察·待处理 | `F-005.md` |
| [F-006](F-006.md) | 观察·待处理 | `F-006.md` |
| [F-007](F-007.md) | 观察·待处理 | `F-007.md` |
| [F-008](F-008.md) | 观察·待处理 | `F-008.md` |
| [F-009](F-009.md) | 观察·待处理 | `F-009.md` |
| [F-010](F-010.md) | 观察·待处理 | `F-010.md` |
| [F-011](F-011.md) | 观察·待处理 | `F-011.md` |
| [F-012](F-012.md) | 观察·待处理 | `F-012.md` |
| [F-013](F-013.md) | 观察·待处理 | `F-013.md` |
| [F-014](F-014.md) | 边界·待处理 | `F-014.md` |
| [F-015](F-015.md) | 边界·待处理 | `F-015.md` |
| [F-016](F-016.md) | 边界·待处理 | `F-016.md` |
| [F-017](F-017.md) | 观察·待处理 | `F-017.md` |
未关闭项(不含已修复/已延后):**13**(F-005, F-006, F-007, F-008, F-009, F-010, F-011, F-012, F-013, F-014, F-015, F-016, F-017)
## 迁移备注
自 TDLMPack 报告拆分迁入;状态字段保持 Pack 原文。未来扫描不再把 scan.sh exit 99、Semgrep、PMD 作为必跑流水线工具(历史正文中的提及可保留,本 README 不要求再跑它们)。
## 一、概况
| 项 | 值 |
|---|---|
| 仓库 | TDLM/thaumicadditions(建档源:`D:\tmp\missing-mod-archive\repos\thaumicadditions`,无 `.git` 的 zip 反编译树) |
| 分支 · HEAD | (源树无 git)· `2f7b9c9696ee6cceb11d93c54592fed30ca218de`(`SCAN_HEAD_SHA.txt`) |
| 最近更新 | 2026-10-26(P1 建档) |
| 形态 | Forge 1.7.10 TC4 附属内容 mod(反编译重托管,jar `Thaumic Additions - 0.41`);java 307(src/main,无 kt/scala/Mixin);updateEntity 20、canUpdate 覆写 0;TESR 16;@SubscribeEvent 含 PlayerTick/ClientTick/HUD;SimpleNetworkWrapper 通道 `thaumicadditions-playnet`;实体 4;IFMLLoadingPlugin 类在树内但本提取无 META-INF 清单 |
| 工具 | 人工形态画像+候选式 grep+命中点全文回读;范式 B1/D1 全仓必扫;周期/渲染/包/空间面按形态选 T1/T4/T15/F1/S1/N1;未跑目标仓构建 |
**计数矩阵**(处置 × 状态;合计 17)
| 处置\状态 | 待处理 | 待裁决 | 已延后 | 已驳回 | 已修复 |
|---|---|---|---|---|---|
| 修 | 0 | 0 | 0 | 0 | 4 |
| 观察 | 10 | 0 | 0 | 0 | 0 |
| 边界 | 3 | 0 | 0 | 0 | 0 |
**扫描轮次**
| 轮次 | 日期 | SHA | 范围 | 净增(修/观/边) |
|---|---|---|---|---|
| P1 | 2026-10-26 | 2f7b9c9 | 建档:B1+D1 必扫+TE/TESR/包/封印/奇点热入口 | 4/10/3 |
## 四、命中(已记)
| 范式 | 定位 | 备注 |
|---|---|---|
| B1 | F-001、F-002 | concurrency;maven content |
| T4 | F-003、F-004 | 空转 TE |
| F1 | F-005、F-006、F-016 | TESR/创造节点/GUI |
| S1 | F-007、F-008 | 奇点;收集印 |
| T1 | F-009–F-013 | 配方/重复 getTE/封印/管 |
| D1 | F-017 | 包路径 INFO |
| N1 | F-014 | 安全相邻 |
| T15 | F-015 | 储罐抽样 |
## 五、排除面
| 范式 | 排除码 | 依据 |
|---|---|---|
| T2 | E-守卫在位 | 未见无变化守卫即恒 `markDirty`/`markBlockForUpdate` 的周期路径;创造节点脏写在 `mfu` 门内(TileCreativeNode.java:145-147) |
| T3 | E-形态全零 | 无全服实例对齐同一 `worldTime%N` 周期谓词的 tick 群 |
| T5 | E-玩家回执 | `TileTaintedCrops` 反射仅坏土掉落分支(`:24-29`);`Class.forName` 在 TA/API 启动或交互沿 |
| T6 | E-守卫在位 | 主要 TE 工作含 `isRemote` 门(如 TileDarkGen/Infuser/Crystallizer);BlockVisTube.playerTick 为方块碰撞箱语义非无门世界扫描 |
| T7 | E-设计本体 | `Util.setBlockMetadata` 用 flag 2(Util.java:31)为元数据同步本体;未见无变化双通道失效广播热路径 |
| T8 | E-形态全零 | 配方表为 ArrayList 线性匹配已记 T1(F-009);无拼接键/契约破损 Map 热查询 |
| T9 | E-形态全零 | 自研实体为奇点/焦点弹/粒子,无「在地静止仍全价移动」物品实体形态 |
| T10 | E-形态全零 | 无红石粉式逐级衰减重通知链 |
| T11 | E-形态全零 | 无锁+装箱/弱键双查型热查询间接层 |
| T12 | E-形态全零 | 无长期混入未就绪项的工作队列全表 drain |
| T13 | E-设计本体 | SealCombo 每 tick new 已并入 F-012(T1);不另立临时对象条 |
| T14 | E-形态全零 | 全仓 `.stream()` 热路径 0 |
| F2 | E-形态全零 | 未见每帧 NBT 反序列化/深拷贝/全树文本重编译链 |
| F3 | E-形态全零 | 无超集过滤缺候选索引的热查询 |
| F4 | E-形态全零 | 同帧同参重复昂贵求值未独立确认(重复 getTE 归 T1) |
| F5 | E-形态全零 | TESR 无每帧射线/无节流世界反查主形态 |
| F6 | E-产品形态 | 无自研网格面剔除;渲染走 Model/原版通道 |
| S2 | E-设计本体 | 周期 `getBlock`/`getTileEntity` 均为已加载邻域作业读取,非「结果可弃的试读加载」 |
| N2 | E-产品形态 | SimpleNetworkWrapper 1.7.10 主线程投递标准形态;无裸 Netty 业务线程改世界 |
| N3 | E-形态全零 | 未见无 shutdown 线程池或静态滞留 World/TE 注册表只增 |
| N4 | E-启动期 | `OpenLibDownloadEngine`/`TACore` 静态下载为类加载/coremod 沿;本提取无 META-INF 清单,运行可达性未证 |
| N5 | E-形态全零 | 出站包直接写 ByteBuf,无每包整份中间拷贝 |
| L1 | E-启动期 | 无 transformer 每类建全树/脚本 O(k·n) 注册表重扫;OpenLib 见 N4 |
| H1 | E-设计本体 | Infuser 事件 post 有配方完成语义;非「无订阅仍每实体每 tick 构造」 |
| M1 | E-形态全零 | 无长生命周期回调捕获仅创建时需要的宿主 |
| M2 | E-形态全零 | 未见本可 interning 的大量等价常驻谓词/形状重复创建热面 |
| J1 | E-形态全零 | 无已确认热路径上可 final 却阻碍内联的短链形态立案 |
| J2 | E-形态全零 | 热路径无定幂 `Math.pow`/仅比较用开方等未廉价化算式立案 |
| J3 | E-形态全零 | `parkNanos`/`yield`/`onSpinWait` 0 |
| J4 | E-形态全零 | 无基本类型数组同构手写循环可换批量原语的热面 |
| J5 | E-形态全零 | 粒子/TESR 非「同纹理逐元素 startDrawing…draw 成对未合并」主形态 |
| J6 | E-形态全零 | 未见同一拍同源多谓词可融合的独立遍历立案 |
## 六、规则反馈
| 范式 | 盲区/建议 | 本仓锚点 |
|---|---|---|
| F1 | 反编译 TESR 常「每帧 new Model + new ResourceLocation」成对出现,规则文案可明示 Model 与 RL 同判 | F-005 RendererDarkGen.java:16/:22 |
| T1 | `Loader.isModLoaded` + `new` 桥接对象出现在 updateEntity 六向环,易被只扫配方表的规则漏掉 | F-011 TileThaumicGenerator.java:71 |
| S1 | 「盒有界但循环内重复查询同一盒」应明示计入频率乘子,勿因 radius 字面量有界直接排除 | F-007 EntitySingularity.java:70 |
| T4 | 1.7.10 默认 `canUpdate()==true`;无覆写 + 空/继承空 updateEntity 即命中,勿写「默认 false」 | F-003/F-004 |
## 七、修订史
| 日期 | 轮次 | 变更 |
|---|---|---|
| 2026-10-26 | P1 | 建档:修 4 / 观 10 / 边 3;源树 HEAD `2f7b9c9696ee6cceb11d93c54592fed30ca218de` |
+2 -2
View File
@@ -22,7 +22,7 @@ plugins {
rootProject.name = 'thaumicadditions'
// Published as uk.potatolab:ThaumicAdditions:<version>-<commit time>-g<sha>, to the organisation's registry.
// Published as uk.potatolab:thaumicadditions:<version>-<commit time>-g<sha>, to the organisation's registry.
stratum {
artifactId = 'ThaumicAdditions'
artifactId = 'thaumicadditions'
}
@@ -19,7 +19,7 @@ public class StructureDefiner {
public final Map<ChunkCoordinates, BlockStack> map = new HashMap();
public final Map<ChunkCoordinates, NBTTagCompound> nbts = new HashMap();
public String Clazz = "mrdimka.api.thaumicadditions.worldgen.BasicStructure";
public String Clazz = "com.pengu.api.thaumicadditions.worldgen.BasicStructure";
public void gatherData(BufferedReader r) {
@@ -63,7 +63,7 @@ import thaumcraft.api.wands.WandRod;
modid = "thaumicadditions",
version = "0.41",
name = "Thaumic Additions",
guiFactory = "mrdimka.thaumcraft.additions.config.ConfigurationGuiFactory",
guiFactory = "com.pengu.thaumcraft.additions.config.ConfigurationGuiFactory",
dependencies = "required-after:Thaumcraft@[4.2.3.5,);required-after:Forge@[10.13.3.137,);required-after:Baubles@[1.0.1.10,)"
)
public class TA {
@@ -138,7 +138,7 @@ public class TA {
proxy.init();
NetworkRegistry.INSTANCE.registerGuiHandler(Reference.instance, new GUIHandler());
if(Loader.isModLoaded("Botania")) {
this.accessClass("mrdimka.thaumcraft.additions.api.others.Botania").init();
this.accessClass("com.pengu.thaumcraft.additions.api.others.Botania").init();
}
BlockDispenser.dispenseBehaviorRegistry.putObject(All.singularity, new BehaviorDispenseSingularity());
@@ -167,7 +167,7 @@ public class TA {
adaminitewood_staff.setGlowing(true);
adaminitewood_staff.setRunes(true);
if(Loader.isModLoaded("Botania")) {
this.accessClass("mrdimka.thaumcraft.additions.api.others.Botania").postInit();
this.accessClass("com.pengu.thaumcraft.additions.api.others.Botania").postInit();
}
All.initVoidChestLoot();
@@ -40,6 +40,11 @@ public class BlockCreativeNode extends BlockContainer {
}
public AxisAlignedBB getCollisionBoundingBoxFromPool(World w, int x, int y, int z) {
if(!w.isRemote) {
// rendering never happens on the server, so the stack walk below can only find nothing
return AxisAlignedBB.getBoundingBox(0.0D, 0.0D, 0.0D, 0.0D, 0.0D, 0.0D);
}
StackTraceElement[] var5 = Thread.currentThread().getStackTrace();
int var6 = var5.length;
@@ -20,6 +20,7 @@ public class BlockHyperNodeCreator extends BlockContainer {
public BlockHyperNodeCreator() {
super(Material.iron);
this.setBlockName("thaumicadditions:hyper_node_creator");
this.setBlockTextureName("thaumicadditions:creative_node");
this.setCreativeTab(TA.tabTA);
this.setBlockUnbreakable();
}
@@ -19,7 +19,7 @@ public class BlockInfuserActivator extends BlockContainer {
public BlockInfuserActivator() {
super(Material.rock);
this.setBlockName("thaumicadditions:infuser_activator");
this.setBlockTextureName("thaumicadditions:infuser_activator");
this.setBlockTextureName("thaumicadditions:infuser/side");
this.setCreativeTab(TA.tabTA);
this.blockHardness = 2.0F;
this.blockResistance = 5.0F;
@@ -22,6 +22,7 @@ public class BlockReturner extends BlockContainer {
TileEntity.addMapping(TileReturner.class, "thaumicadditions:Returner");
this.setBlockUnbreakable();
this.setBlockName("thaumicadditions:returner_block");
this.setBlockTextureName("thaumicadditions:void");
}
public void getSubBlocks(Item i, CreativeTabs c, List l) {}
@@ -2,12 +2,32 @@ package com.pengu.thaumcraft.additions.config;
import com.pengu.thaumcraft.additions.config.modcfg;
import cpw.mods.fml.client.config.GuiConfig;
import cpw.mods.fml.client.config.IConfigElement;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.client.gui.GuiScreen;
import net.minecraftforge.common.config.ConfigCategory;
import net.minecraftforge.common.config.ConfigElement;
import net.minecraftforge.common.config.Configuration;
public class ModConfigurationGui extends GuiConfig {
public ModConfigurationGui(GuiScreen gui) {
super(gui, (new ConfigElement(modcfg.getConfiguration().getCategory("general"))).getChildElements(), "thaumicadditions", true, true, GuiConfig.getAbridgedConfigPath(modcfg.getConfiguration().toString()));
super(gui, getCategoryElements(), "thaumicadditions", true, true, GuiConfig.getAbridgedConfigPath(modcfg.getConfiguration().toString()));
}
// 选项都在 Customization、misc、ClientSide 里,general 是空的,所以按实际分类列出来。
private static List<IConfigElement> getCategoryElements() {
Configuration cfg = modcfg.getConfiguration();
List<IConfigElement> elements = new ArrayList<IConfigElement>();
for(String name : cfg.getCategoryNames()) {
ConfigCategory category = cfg.getCategory(name);
if(!category.getValues().isEmpty()) {
elements.add(new ConfigElement(category));
}
}
return elements;
}
}
@@ -67,10 +67,18 @@ public class EntitySingularity extends EntityAlumentum {
List l;
List l2;
int i;
// position and radius do not change inside the loop, so the box is built once and the entity lists are
// only queried again after a round that could have added or removed entities (alumentum, block breaking)
AxisAlignedBB ent = AxisAlignedBB.getBoundingBox(this.posX - (double)this.radius, this.posY - (double)this.radius, this.posZ - (double)this.radius, this.posX + (double)this.radius, this.posY + (double)this.radius, this.posZ + (double)this.radius);
l = this.worldObj.getEntitiesWithinAABB(Entity.class, ent);
l2 = this.worldObj.getEntitiesWithinAABB(EntityLivingBase.class, ent);
boolean entitiesChanged = false;
for(p = 0; p < 128; ++p) {
AxisAlignedBB ent = AxisAlignedBB.getBoundingBox(this.posX - (double)this.radius, this.posY - (double)this.radius, this.posZ - (double)this.radius, this.posX + (double)this.radius, this.posY + (double)this.radius, this.posZ + (double)this.radius);
l = this.worldObj.getEntitiesWithinAABB(Entity.class, ent);
l2 = this.worldObj.getEntitiesWithinAABB(EntityLivingBase.class, ent);
if(entitiesChanged) {
l = this.worldObj.getEntitiesWithinAABB(Entity.class, ent);
l2 = this.worldObj.getEntitiesWithinAABB(EntityLivingBase.class, ent);
entitiesChanged = false;
}
double ry;
double ey;
@@ -103,6 +111,7 @@ public class EntitySingularity extends EntityAlumentum {
var24.posZ = ez;
var24.inGround = true;
this.worldObj.spawnEntityInWorld(var24);
entitiesChanged = true;
}
}
@@ -122,23 +131,6 @@ public class EntitySingularity extends EntityAlumentum {
}
int var22;
for(i = 0; i < 16; ++i) {
for(var22 = 0; var22 < l2.size(); ++var22) {
double rz = ((EntityLivingBase)l2.get(var22)).posX;
double ey1 = ((EntityLivingBase)l2.get(var22)).posY;
double ez1 = ((EntityLivingBase)l2.get(var22)).posZ;
double motionX1 = ((EntityLivingBase)l2.get(var22)).motionX;
double motionY1 = ((EntityLivingBase)l2.get(var22)).motionY;
double motionZ1 = ((EntityLivingBase)l2.get(var22)).motionZ;
motionX1 = this.posX - rz;
motionY1 = this.posY - ey1 + (double)(this.ticksExisted < 400?(float)this.ticksExisted / 400.0F * 4.0F:4.0F);
motionZ1 = this.posZ - ez1;
((EntityLivingBase)l2.get(var22)).motionX = motionX1 / 10.0D;
((EntityLivingBase)l2.get(var22)).motionY = motionY1 / 10.0D;
((EntityLivingBase)l2.get(var22)).motionZ = motionZ1 / 10.0D;
}
}
i = (int)this.posX;
var22 = (int)this.posY;
int var23 = (int)this.posZ;
@@ -153,6 +145,7 @@ public class EntitySingularity extends EntityAlumentum {
}
this.worldObj.setBlockToAir(i, var22, var23);
entitiesChanged = true;
}
}
@@ -12,6 +12,8 @@ import org.lwjgl.opengl.GL11;
public class GUICondensator extends GuiContainer {
private static final ResourceLocation TEXTURE = new ResourceLocation("thaumicadditions", "textures/gui/guicondenser.png");
private TileOldCondensator mw;
@@ -23,7 +25,7 @@ public class GUICondensator extends GuiContainer {
}
public void drawGuiContainerBackgroundLayer(float p_146976_1_, int p_146976_2_, int p_146976_3_) {
Minecraft.getMinecraft().getTextureManager().bindTexture(new ResourceLocation("thaumicadditions", "textures/gui/guicondenser.png"));
Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE);
this.drawTexturedModalRect(this.guiLeft, this.guiTop, 0, 0, this.xSize, this.ySize);
int i = this.mw.getProgressScaled(36);
GL11.glPushMatrix();
@@ -12,6 +12,8 @@ import net.minecraft.util.ResourceLocation;
public class GUIDarkGenerator extends GuiContainer {
private static final ResourceLocation TEXTURE = new ResourceLocation("thaumicadditions", "textures/gui/guidarkgen.png");
private TileDarkGen mw;
@@ -23,7 +25,7 @@ public class GUIDarkGenerator extends GuiContainer {
}
public void drawGuiContainerBackgroundLayer(float p_146976_1_, int p_146976_2_, int p_146976_3_) {
Minecraft.getMinecraft().getTextureManager().bindTexture(new ResourceLocation("thaumicadditions", "textures/gui/guidarkgen.png"));
Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE);
this.drawTexturedModalRect(this.guiLeft, this.guiTop, 0, 0, this.xSize, this.ySize);
this.drawTexturedModalRect(this.guiLeft + 84, this.guiTop + 44, 192, this.mw.getWorldObj().getMoonPhase() * 8, 8, 8);
this.drawTexturedModalRect(this.guiLeft + 84 - 4, this.guiTop + 44 - 20, 176, LightUtil.getLightValue(this.mw.getWorldObj(), this.mw.xCoord, this.mw.yCoord, this.mw.zCoord) * 16, 16, 16);
@@ -12,6 +12,8 @@ import net.minecraft.util.StatCollector;
public class GUIDarkInfuser extends GuiContainer {
private static final ResourceLocation TEXTURE = new ResourceLocation("thaumicadditions", "textures/gui/guidarkinfuser.png");
private TileDarkInfuser mw;
@@ -23,7 +25,7 @@ public class GUIDarkInfuser extends GuiContainer {
}
public void drawGuiContainerBackgroundLayer(float p_146976_1_, int p_146976_2_, int p_146976_3_) {
Minecraft.getMinecraft().getTextureManager().bindTexture(new ResourceLocation("thaumicadditions", "textures/gui/guidarkinfuser.png"));
Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE);
this.drawTexturedModalRect(this.guiLeft, this.guiTop, 0, 0, this.xSize, this.ySize);
int i;
if(this.mw.cookTime > 0) {
@@ -11,6 +11,8 @@ import net.minecraft.util.ResourceLocation;
public class GUIHyperNodeCreator extends GuiContainer {
private static final ResourceLocation TEXTURE = new ResourceLocation("thaumicadditions", "textures/gui/guihypernodecreator.png");
private TileHyperNodeCreator mw;
@@ -22,7 +24,7 @@ public class GUIHyperNodeCreator extends GuiContainer {
}
public void drawGuiContainerBackgroundLayer(float p_146976_1_, int p_146976_2_, int p_146976_3_) {
Minecraft.getMinecraft().getTextureManager().bindTexture(new ResourceLocation("thaumicadditions", "textures/gui/guihypernodecreator.png"));
Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE);
this.drawTexturedModalRect(this.guiLeft, this.guiTop, 0, 0, this.xSize, this.ySize);
}
@@ -10,6 +10,8 @@ import net.minecraft.util.ResourceLocation;
public class GUIInfuser extends GuiContainer {
private static final ResourceLocation TEXTURE = new ResourceLocation("thaumicadditions", "textures/gui/guiinfuser.png");
private TileInfuser mw;
@@ -21,7 +23,7 @@ public class GUIInfuser extends GuiContainer {
}
public void drawGuiContainerBackgroundLayer(float p_146976_1_, int p_146976_2_, int p_146976_3_) {
Minecraft.getMinecraft().getTextureManager().bindTexture(new ResourceLocation("thaumicadditions", "textures/gui/guiinfuser.png"));
Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE);
this.drawTexturedModalRect(this.guiLeft, this.guiTop, 0, 0, this.xSize, this.ySize);
if(this.mw.cookTime > 0) {
int i = this.mw.getCookProgressScaled(47);
@@ -14,6 +14,8 @@ import net.minecraft.world.World;
public class GUISealGlobe extends GuiContainer {
private static final ResourceLocation TEXTURE = new ResourceLocation("thaumicadditions", "textures/gui/guicrystalball.png");
private World world;
private int x;
private int y;
@@ -35,7 +37,7 @@ public class GUISealGlobe extends GuiContainer {
}
public void drawGuiContainerBackgroundLayer(float p_146976_1_, int p_146976_2_, int p_146976_3_) {
Minecraft.getMinecraft().getTextureManager().bindTexture(new ResourceLocation("thaumicadditions", "textures/gui/guicrystalball.png"));
Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE);
this.drawTexturedModalRect(this.guiLeft, this.guiTop, 0, 0, this.xSize, this.ySize);
if(this.dir == EnumRise.UP) {
this.color += 4.210651F;
@@ -10,6 +10,8 @@ import net.minecraft.util.ResourceLocation;
public class GUIThaumicCrystallizer extends GuiContainer {
private static final ResourceLocation TEXTURE = new ResourceLocation("thaumicadditions", "textures/gui/guicrystalizer.png");
private TileThaumCrystallizer mw;
@@ -21,7 +23,7 @@ public class GUIThaumicCrystallizer extends GuiContainer {
}
public void drawGuiContainerBackgroundLayer(float p_146976_1_, int p_146976_2_, int p_146976_3_) {
Minecraft.getMinecraft().getTextureManager().bindTexture(new ResourceLocation("thaumicadditions", "textures/gui/guicrystalizer.png"));
Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE);
this.drawTexturedModalRect(this.guiLeft, this.guiTop, 0, 0, this.xSize, this.ySize);
int i = this.mw.getCookProgressScaled(47);
this.drawTexturedModalRect(this.guiLeft + 160, this.guiTop + 105 + 47 - i, 176, 47 - i, 9, i);
@@ -10,6 +10,8 @@ import net.minecraft.util.ResourceLocation;
public class GUIThaumicGenerator extends GuiContainer {
private static final ResourceLocation TEXTURE = new ResourceLocation("thaumicadditions", "textures/gui/guigenerator.png");
private TileThaumicGenerator mw;
@@ -21,7 +23,7 @@ public class GUIThaumicGenerator extends GuiContainer {
}
public void drawGuiContainerBackgroundLayer(float p_146976_1_, int p_146976_2_, int p_146976_3_) {
Minecraft.getMinecraft().getTextureManager().bindTexture(new ResourceLocation("thaumicadditions", "textures/gui/guigenerator.png"));
Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE);
this.drawTexturedModalRect(this.guiLeft, this.guiTop, 0, 0, this.xSize, this.ySize);
int i = this.mw.amount * 47 / this.mw.maxAmount;
this.drawTexturedModalRect(this.guiLeft + 47, this.guiTop + 22 + 47 - i, 102, 47 - i, 9, i);
@@ -11,6 +11,8 @@ import net.minecraft.util.ResourceLocation;
public class GUIThaumicRestorer extends GuiContainer {
private static final ResourceLocation TEXTURE = new ResourceLocation("thaumicadditions", "textures/gui/guirepairer.png");
private TileThaumicRestorer res;
@@ -22,7 +24,7 @@ public class GUIThaumicRestorer extends GuiContainer {
}
public void drawGuiContainerBackgroundLayer(float p_146976_1_, int p_146976_2_, int p_146976_3_) {
Minecraft.getMinecraft().getTextureManager().bindTexture(new ResourceLocation("thaumicadditions", "textures/gui/guirepairer.png"));
Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE);
this.drawTexturedModalRect(this.guiLeft, this.guiTop, 0, 0, this.xSize, this.ySize);
int i = this.res.tick * 31 / 5;
this.drawTexturedModalRect(this.guiLeft + 135, this.guiTop + 16 + 31 - i, 176, 31 - i, 7, i);
@@ -9,6 +9,8 @@ import net.minecraft.util.ResourceLocation;
public class GUIVoidChest extends GuiContainer {
private static final ResourceLocation TEXTURE = new ResourceLocation("thaumicadditions", "textures/gui/guivoidchest.png");
private TileVoidChest mw;
@@ -20,7 +22,7 @@ public class GUIVoidChest extends GuiContainer {
}
public void drawGuiContainerBackgroundLayer(float p_146976_1_, int p_146976_2_, int p_146976_3_) {
Minecraft.getMinecraft().getTextureManager().bindTexture(new ResourceLocation("thaumicadditions", "textures/gui/guivoidchest.png"));
Minecraft.getMinecraft().getTextureManager().bindTexture(TEXTURE);
this.drawTexturedModalRect(this.guiLeft, this.guiTop, 0, 0, this.xSize, this.ySize);
}
@@ -58,8 +58,9 @@ public class TileVisTube extends TileThaumcraft implements IMultiBlockPart, ITub
x = this.xCoord + ForgeDirectionHelper.getForgeDirectionXApplyed(fd);
y = this.yCoord + ForgeDirectionHelper.getForgeDirectionYApplyed(fd);
z = this.zCoord + ForgeDirectionHelper.getForgeDirectionZApplyed(fd);
if(this.worldObj.getTileEntity(x, y, z) instanceof ITubeConnectable) {
ITubeConnectable tube = (ITubeConnectable)this.worldObj.getTileEntity(x, y, z);
TileEntity neighbour = this.worldObj.getTileEntity(x, y, z); // read once per side
if(neighbour instanceof ITubeConnectable) {
ITubeConnectable tube = (ITubeConnectable)neighbour;
this.connectivity.put(fd, Boolean.valueOf(tube.canConnect(fd.getOpposite())));
if(((Boolean)this.connectivity.get(fd)).booleanValue()) {
this.connectivityExtended.put(fd, Boolean.valueOf(tube.shouldExtendRenderingForTubes(fd.getOpposite())));
@@ -71,8 +72,8 @@ public class TileVisTube extends TileThaumcraft implements IMultiBlockPart, ITub
this.connectivityExtended.put(fd, Boolean.valueOf(false));
}
if(this.worldObj.getTileEntity(x, y, z) instanceof ITubable) {
ITubable var12 = (ITubable)this.worldObj.getTileEntity(x, y, z);
if(neighbour instanceof ITubable) {
ITubable var12 = (ITubable)neighbour;
if(var12.canConnect(fd.getOpposite()) && !(var12 instanceof TileVisTube)) {
if(var12.canAccept(fd.getOpposite(), MagicType.VIS) && this.ejectVis(MagicType.VIS, var12.acceptVis(MagicType.VIS, this.grid.vis, fd.getOpposite()), fd) > 0) {
;
@@ -95,7 +96,8 @@ public class TileVisTube extends TileThaumcraft implements IMultiBlockPart, ITub
x = this.xCoord + ForgeDirectionHelper.getForgeDirectionXApplyed(fd);
y = this.yCoord + ForgeDirectionHelper.getForgeDirectionYApplyed(fd);
z = this.zCoord + ForgeDirectionHelper.getForgeDirectionZApplyed(fd);
TileVisTube var13 = this.world().getTileEntity(x, y, z) instanceof TileVisTube?(TileVisTube)this.world().getTileEntity(x, y, z):null;
TileEntity neighbour = this.world().getTileEntity(x, y, z);
TileVisTube var13 = neighbour instanceof TileVisTube?(TileVisTube)neighbour:null;
if(var13 != null && var13.canConnect(fd.getOpposite())) {
VisGrid grid0 = this.grid;
VisGrid grid1 = var13.grid;
@@ -14,20 +14,11 @@ public class TileOldReinforcedTank extends TileTankBasic {
}
public void updateEntity() {
if(!(this.worldObj.getBlock(this.xCoord, this.yCoord + 1, this.zCoord) instanceof BlockTankBasic) && !(this.worldObj.getBlock(this.xCoord, this.yCoord - 1, this.zCoord) instanceof BlockTankBasic) && this.worldObj.getBlockMetadata(this.xCoord, this.yCoord, this.zCoord) != 0) {
Util.setBlockMetadata(this.worldObj, this.xCoord, this.yCoord, this.zCoord, 0);
}
if(!(this.worldObj.getBlock(this.xCoord, this.yCoord + 1, this.zCoord) instanceof BlockTankBasic) && this.worldObj.getBlock(this.xCoord, this.yCoord - 1, this.zCoord) instanceof BlockTankBasic && this.worldObj.getBlockMetadata(this.xCoord, this.yCoord, this.zCoord) != 1) {
Util.setBlockMetadata(this.worldObj, this.xCoord, this.yCoord, this.zCoord, 1);
}
if(this.worldObj.getBlock(this.xCoord, this.yCoord + 1, this.zCoord) instanceof BlockTankBasic && !(this.worldObj.getBlock(this.xCoord, this.yCoord - 1, this.zCoord) instanceof BlockTankBasic) && this.worldObj.getBlockMetadata(this.xCoord, this.yCoord, this.zCoord) != 2) {
Util.setBlockMetadata(this.worldObj, this.xCoord, this.yCoord, this.zCoord, 2);
}
if(this.worldObj.getBlock(this.xCoord, this.yCoord + 1, this.zCoord) instanceof BlockTankBasic && this.worldObj.getBlock(this.xCoord, this.yCoord - 1, this.zCoord) instanceof BlockTankBasic && this.worldObj.getBlockMetadata(this.xCoord, this.yCoord, this.zCoord) != 3) {
Util.setBlockMetadata(this.worldObj, this.xCoord, this.yCoord, this.zCoord, 3);
boolean above = this.worldObj.getBlock(this.xCoord, this.yCoord + 1, this.zCoord) instanceof BlockTankBasic;
boolean below = this.worldObj.getBlock(this.xCoord, this.yCoord - 1, this.zCoord) instanceof BlockTankBasic;
int wantedMeta = TileTankBasic.connectionMeta(above, below);
if(this.worldObj.getBlockMetadata(this.xCoord, this.yCoord, this.zCoord) != wantedMeta) {
Util.setBlockMetadata(this.worldObj, this.xCoord, this.yCoord, this.zCoord, wantedMeta);
}
boolean ext = this.worldObj.getTileEntity(this.xCoord, this.yCoord + 1, this.zCoord) instanceof TileOldReinforcedTank && this.vis + this.taint < this.capacity;
@@ -2,7 +2,6 @@ package com.pengu.thaumcraft.additions.playnet.packtetmng;
import com.pengu.api.thaumicadditions.enums.EnumAT;
import com.pengu.thaumcraft.additions.utils.hud.HUD;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
@@ -16,59 +15,68 @@ public class PacketAuraVis implements IMessage, IMessageHandler<PacketAuraVis, I
public void setData(EnumAT[] aspects, int[] amounts) {
this.aspects = aspects;
this.amts = amounts;
this.aspects = aspects;
this.amts = amounts;
}
public IMessage onMessage(PacketAuraVis message, MessageContext ctx) {
try {
FMLLog.info("Received!", new Object[0]);
for(int i = 0; i < Math.min(message.aspects.length, message.amts.length); ++i) {
HUD.currentAspects.aspects.put(Aspect.getAspect(message.aspects[i].getAspect()), Integer.valueOf(message.amts[i]));
}
} catch (Throwable var4) {
;
}
return null;
try {
for(int i = 0; i < Math.min(message.aspects.length, message.amts.length); ++i) {
HUD.currentAspects.aspects.put(Aspect.getAspect(message.aspects[i].getAspect()), Integer.valueOf(message.amts[i]));
}
} catch (Throwable var4) {
;
}
return null;
}
public void fromBytes(ByteBuf buf) {
this.amts = new int[buf.readInt()];
int i;
for(i = 0; i < this.amts.length; ++i) {
this.amts[i] = buf.readInt();
}
this.aspects = new EnumAT[buf.readInt()];
for(i = 0; i < this.aspects.length; ++i) {
this.aspects[i] = EnumAT.getFrom(buf.readInt());
}
this.amts = new int[checkedLength(buf)];
int i;
for(i = 0; i < this.amts.length; ++i) {
this.amts[i] = buf.readInt();
}
this.aspects = new EnumAT[checkedLength(buf)];
for(i = 0; i < this.aspects.length; ++i) {
this.aspects[i] = EnumAT.getFrom(buf.readInt());
}
}
// Each element is one int: a count larger than what is left in the packet is malformed
// (it used to size the array straight from the wire).
private static int checkedLength(ByteBuf buf) {
int n = buf.readInt();
if(n < 0 || n > buf.readableBytes() / 4) {
throw new IllegalArgumentException("bad aura packet length " + n);
}
return n;
}
public void toBytes(ByteBuf buf) {
buf.writeInt(this.amts.length);
int[] var2 = this.amts;
int var3 = var2.length;
int var4;
for(var4 = 0; var4 < var3; ++var4) {
int a = var2[var4];
buf.writeInt(a);
}
buf.writeInt(this.aspects.length);
EnumAT[] var6 = this.aspects;
var3 = var6.length;
for(var4 = 0; var4 < var3; ++var4) {
EnumAT var7 = var6[var4];
buf.writeInt(var7.id);
}
buf.writeInt(this.amts.length);
int[] var2 = this.amts;
int var3 = var2.length;
int var4;
for(var4 = 0; var4 < var3; ++var4) {
int a = var2[var4];
buf.writeInt(a);
}
buf.writeInt(this.aspects.length);
EnumAT[] var6 = this.aspects;
var3 = var6.length;
for(var4 = 0; var4 < var3; ++var4) {
EnumAT var7 = var6[var4];
buf.writeInt(var7.id);
}
}
}
@@ -10,16 +10,19 @@ import org.lwjgl.opengl.GL11;
public class RendererDarkGen extends TileEntitySpecialRenderer {
private static final ResourceLocation TEXTURE = new ResourceLocation("thaumicadditions", "textures/models/DarkGen.png");
private final ModelDarkGen modelDarkGen = new ModelDarkGen(); // one instance (each new one also compiled fresh display lists)
public void renderTileEntityAt(TileEntity te, double x, double y, double z, float par1float) {
GL11.glPushMatrix();
GL11.glTranslatef((float)x + 0.5F, (float)y + 1.5F, (float)z + 0.5F);
ResourceLocation textures = new ResourceLocation("thaumicadditions", "textures/models/DarkGen.png");
ResourceLocation textures = TEXTURE;
Minecraft.getMinecraft().renderEngine.bindTexture(textures);
GL11.glPushMatrix();
GL11.glRotatef(180.0F, 0.0F, 0.0F, 1.0F);
GL11.glPushMatrix();
GL11.glRotatef(0.0F, 0.0F, 1.0F, 0.0F);
(new ModelDarkGen()).render((Entity)null, 0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F, false);
this.modelDarkGen.render((Entity)null, 0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F, false);
GL11.glPopMatrix();
GL11.glPopMatrix();
GL11.glPopMatrix();
@@ -11,16 +11,20 @@ import org.lwjgl.opengl.GL11;
public class RendererHyperNodeCreator extends TileEntitySpecialRenderer {
private static final ResourceLocation TEXTURE_PRIMALS = new ResourceLocation("thaumicadditions", "textures/models/HyperNodeCreator_primals.png");
private static final ResourceLocation TEXTURE_ALL = new ResourceLocation("thaumicadditions", "textures/models/HyperNodeCreator_all.png");
private final ModelHyperNodeCreator modelHyperNodeCreator = new ModelHyperNodeCreator(); // one instance (each new one also compiled fresh display lists)
public void renderTileEntityAt(TileEntity te, double x, double y, double z, float par1float) {
GL11.glPushMatrix();
GL11.glTranslatef((float)x + 0.5F, (float)y + 1.5F, (float)z + 0.5F);
ResourceLocation textures = new ResourceLocation("thaumicadditions", "textures/models/HyperNodeCreator_" + (((TileHyperNodeCreator)te).primalsOnly?"primals":"all") + ".png");
ResourceLocation textures = ((TileHyperNodeCreator)te).primalsOnly ? TEXTURE_PRIMALS : TEXTURE_ALL;
Minecraft.getMinecraft().renderEngine.bindTexture(textures);
GL11.glPushMatrix();
GL11.glRotatef(180.0F, 0.0F, 0.0F, 1.0F);
GL11.glPushMatrix();
GL11.glRotatef(0.0F, 0.0F, 1.0F, 0.0F);
(new ModelHyperNodeCreator()).render((Entity)null, 0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F, ((TileHyperNodeCreator)te).node);
this.modelHyperNodeCreator.render((Entity)null, 0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F, ((TileHyperNodeCreator)te).node);
GL11.glPopMatrix();
GL11.glPopMatrix();
GL11.glPopMatrix();
@@ -13,15 +13,21 @@ import org.lwjgl.opengl.GL11;
public class RendererInfuser extends TileEntitySpecialRenderer {
private static final ResourceLocation TOP = new ResourceLocation("thaumicadditions", "textures/models/InfuserTop.png");
private static final ResourceLocation TOP_DARK = new ResourceLocation("thaumicadditions", "textures/models/InfuserTopDark.png");
private static final ResourceLocation SYMBOL = new ResourceLocation("thaumicadditions", "textures/models/infusersymbol.png");
private static final ResourceLocation SYMBOL_DARK = new ResourceLocation("thaumicadditions", "textures/models/darkinfusersymbol.png");
private final ModelTileInfuser modelTileInfuser = new ModelTileInfuser(); // one instance (each new one also compiled fresh display lists)
public void renderTileEntityAt(TileEntity te, double x, double y, double z, float par1float) {
GL11.glPushMatrix();
GL11.glTranslatef((float)x + 0.5F, (float)y + 1.5F, (float)z + 0.5F);
Minecraft.getMinecraft().renderEngine.bindTexture(new ResourceLocation("thaumicadditions", "textures/models/InfuserTop" + (te instanceof TileDarkInfuser?"Dark":"") + ".png"));
Minecraft.getMinecraft().renderEngine.bindTexture((te instanceof TileDarkInfuser ? TOP_DARK : TOP));
GL11.glPushMatrix();
GL11.glRotatef(180.0F, 0.0F, 0.0F, 1.0F);
GL11.glPushMatrix();
GL11.glRotatef(0.0F, 0.0F, 1.0F, 0.0F);
(new ModelTileInfuser()).render((Entity)null, 0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F, false);
this.modelTileInfuser.render((Entity)null, 0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F, false);
GL11.glPopMatrix();
GL11.glPopMatrix();
GL11.glPopMatrix();
@@ -33,7 +39,7 @@ public class RendererInfuser extends TileEntitySpecialRenderer {
GL11.glTranslatef((float)x, (float)y + 0.5F - 0.2185F, (float)z);
}
Minecraft.getMinecraft().renderEngine.bindTexture(new ResourceLocation("thaumicadditions", "textures/models/infusersymbol.png"));
Minecraft.getMinecraft().renderEngine.bindTexture(SYMBOL);
if(inf.cookTime > 0) {
GL11.glTranslatef((float)x + 0.5F, (float)y + 0.5F - 0.2185F, (float)z + 0.5F);
GL11.glRotatef((float)Minecraft.getSystemTime() % 3600.0F / 10.0F, 0.0F, 1.0F, 0.0F);
@@ -50,7 +56,7 @@ public class RendererInfuser extends TileEntitySpecialRenderer {
GL11.glTranslatef((float)x, (float)y + 0.5F - 0.2185F, (float)z);
}
Minecraft.getMinecraft().renderEngine.bindTexture(new ResourceLocation("thaumicadditions", "textures/models/darkinfusersymbol.png"));
Minecraft.getMinecraft().renderEngine.bindTexture(SYMBOL_DARK);
if(inf1.cookTime + inf1.cookTimeTaint > 0) {
GL11.glTranslatef((float)x + 0.5F, (float)y + 0.5F - 0.2185F, (float)z + 0.5F);
GL11.glRotatef((float)Minecraft.getSystemTime() % 3600.0F / 10.0F, 0.0F, 1.0F, 0.0F);
@@ -13,10 +13,14 @@ import thaumcraft.client.renderers.item.ItemWandRenderer;
public class RendererInfuserActivator extends TileEntitySpecialRenderer {
private static final ResourceLocation TEXTURE = new ResourceLocation("thaumicadditions", "textures/models/InfuserActivator.png");
private final ModelInfuserActivator modelInfuserActivator = new ModelInfuserActivator(); // one instance (each new one also compiled fresh display lists)
private final ItemWandRenderer wandRenderer = new ItemWandRenderer();
public void renderTileEntityAt(TileEntity te, double x, double y, double z, float par1float) {
GL11.glPushMatrix();
GL11.glTranslatef((float)x + 0.5F, (float)y + 1.5F, (float)z + 0.5F);
ResourceLocation textures = new ResourceLocation("thaumicadditions", "textures/models/InfuserActivator.png");
ResourceLocation textures = TEXTURE;
GL11.glPushMatrix();
GL11.glRotatef(180.0F, 0.0F, 0.0F, 1.0F);
GL11.glPushMatrix();
@@ -28,13 +32,13 @@ public class RendererInfuserActivator extends TileEntitySpecialRenderer {
float rot = te instanceof TileInfuserActivator?(float)((TileInfuserActivator)te).beforeclick:0.0F;
rot = -rot;
GL11.glTranslatef(0.0F, 1.4F + rot / 360.0F, 0.0F);
(new ItemWandRenderer()).renderItem(ItemRenderType.ENTITY, ((TileInfuserActivator)te).wandstack, new Object[0]);
this.wandRenderer.renderItem(ItemRenderType.ENTITY, ((TileInfuserActivator)te).wandstack, new Object[0]);
GL11.glColor3f(1.0F, 1.0F, 1.0F);
GL11.glEnable(2896);
GL11.glPopMatrix();
GL11.glPopMatrix();
Minecraft.getMinecraft().renderEngine.bindTexture(textures);
(new ModelInfuserActivator()).render((Entity)null, 0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F);
this.modelInfuserActivator.render((Entity)null, 0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F);
GL11.glPopMatrix();
GL11.glPopMatrix();
GL11.glPopMatrix();
@@ -12,6 +12,10 @@ import org.lwjgl.opengl.GL11;
public class RendererSeal extends TileEntitySpecialRenderer {
private static final ResourceLocation SEAL = new ResourceLocation("thaumicadditions", "textures/models/seal.png");
private static final ResourceLocation SEAL_OVER = new ResourceLocation("thaumicadditions", "textures/models/seal_over.png");
private final ModelSeal modelSeal = new ModelSeal(); // one instance (each new one also compiled fresh display lists)
ResourceLocation f0 = new ResourceLocation("thaumicadditions", "textures/blocks/seal_/s_0.png");
ResourceLocation f1 = new ResourceLocation("thaumicadditions", "textures/blocks/seal_/s_1.png");
ResourceLocation f2 = new ResourceLocation("thaumicadditions", "textures/blocks/seal_/s_2.png");
@@ -38,14 +42,14 @@ public class RendererSeal extends TileEntitySpecialRenderer {
GL11.glTranslatef(1.0F / (ori == 5?256.0F:-256.0F), 2.32F, 0.0F);
}
this.bindTexture(new ResourceLocation("thaumicadditions", "textures/models/seal.png"));
(new ModelSeal()).render((Entity)null, 0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F, te.getBlockMetadata() < 6?ForgeDirection.OPPOSITES[te.getBlockMetadata()]:0);
this.bindTexture(new ResourceLocation("thaumicadditions", "textures/models/seal_over.png"));
this.bindTexture(SEAL);
this.modelSeal.render((Entity)null, 0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F, te.getBlockMetadata() < 6?ForgeDirection.OPPOSITES[te.getBlockMetadata()]:0);
this.bindTexture(SEAL_OVER);
float r0 = (float)(((TileSeal)te).color >> 16 & 255) / 255.0F;
float g0 = (float)(((TileSeal)te).color >> 8 & 255) / 255.0F;
float b0 = (float)(((TileSeal)te).color & 255) / 255.0F;
GL11.glColor3f(r0, g0, b0);
(new ModelSeal()).render((Entity)null, 0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F, te.getBlockMetadata() < 6?ForgeDirection.OPPOSITES[te.getBlockMetadata()]:0);
this.modelSeal.render((Entity)null, 0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F, te.getBlockMetadata() < 6?ForgeDirection.OPPOSITES[te.getBlockMetadata()]:0);
GL11.glPopMatrix();
GL11.glPushMatrix();
float r1;
@@ -58,7 +62,7 @@ public class RendererSeal extends TileEntitySpecialRenderer {
b1 = (float)(((TileSeal)te).f.getType().getColor() & 255) / 255.0F;
GL11.glPushMatrix();
GL11.glColor3f(r1, g1, b1);
(new ModelSeal()).render((Entity)null, 0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F, te.getBlockMetadata() < 6?ForgeDirection.OPPOSITES[te.getBlockMetadata()]:0);
this.modelSeal.render((Entity)null, 0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F, te.getBlockMetadata() < 6?ForgeDirection.OPPOSITES[te.getBlockMetadata()]:0);
GL11.glPopMatrix();
}
@@ -69,7 +73,7 @@ public class RendererSeal extends TileEntitySpecialRenderer {
b1 = (float)(((TileSeal)te).s.getType().getColor() & 255) / 255.0F;
GL11.glPushMatrix();
GL11.glColor3f(r1, g1, b1);
(new ModelSeal()).render((Entity)null, 0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F, te.getBlockMetadata() < 6?ForgeDirection.OPPOSITES[te.getBlockMetadata()]:0);
this.modelSeal.render((Entity)null, 0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F, te.getBlockMetadata() < 6?ForgeDirection.OPPOSITES[te.getBlockMetadata()]:0);
GL11.glPopMatrix();
}
@@ -80,7 +84,7 @@ public class RendererSeal extends TileEntitySpecialRenderer {
b1 = (float)(((TileSeal)te).t.getType().getColor() & 255) / 255.0F;
GL11.glPushMatrix();
GL11.glColor3f(r1, g1, b1);
(new ModelSeal()).render((Entity)null, 0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F, te.getBlockMetadata() < 6?ForgeDirection.OPPOSITES[te.getBlockMetadata()]:0);
this.modelSeal.render((Entity)null, 0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F, te.getBlockMetadata() < 6?ForgeDirection.OPPOSITES[te.getBlockMetadata()]:0);
GL11.glPopMatrix();
}
@@ -11,16 +11,19 @@ import thaumcraft.common.tiles.TileJarFillable;
public class RendererSymboller extends TileEntitySpecialRenderer {
private static final ResourceLocation TEXTURE = new ResourceLocation("thaumicadditions", "textures/models/TileSealSymboller.png");
private final ModelTileSealSymboller modelTileSealSymboller = new ModelTileSealSymboller(); // one instance (each new one also compiled fresh display lists)
public void renderTileEntityAt(TileEntity te, double x, double y, double z, float floatt) {
GL11.glPushMatrix();
GL11.glTranslatef((float)x + 0.5F, (float)y + 1.5F, (float)z + 0.5F);
ResourceLocation textures = new ResourceLocation("thaumicadditions", "textures/models/TileSealSymboller.png");
ResourceLocation textures = TEXTURE;
Minecraft.getMinecraft().renderEngine.bindTexture(textures);
GL11.glPushMatrix();
GL11.glRotatef(180.0F, 0.0F, 0.0F, 1.0F);
GL11.glPushMatrix();
GL11.glRotatef(0.0F, 0.0F, 1.0F, 0.0F);
(new ModelTileSealSymboller()).render((Entity)null, 0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F, te.getWorldObj().getTileEntity(te.xCoord, te.yCoord + 1, te.zCoord) != null && te.getWorldObj().getTileEntity(te.xCoord, te.yCoord + 1, te.zCoord) instanceof TileJarFillable);
this.modelTileSealSymboller.render((Entity)null, 0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F, te.getWorldObj().getTileEntity(te.xCoord, te.yCoord + 1, te.zCoord) instanceof TileJarFillable);
GL11.glPopMatrix();
GL11.glPopMatrix();
GL11.glPopMatrix();
@@ -14,10 +14,18 @@ import org.lwjgl.opengl.GL11;
public class RendererTankBasic extends TileEntitySpecialRenderer {
private static final ResourceLocation[] LIQUID_FRAMES = new ResourceLocation[16];
static {
for(int i = 0; i < LIQUID_FRAMES.length; ++i) {
LIQUID_FRAMES[i] = new ResourceLocation("thaumicadditions", "textures/models/TankLiquid/" + i + ".png");
}
}
private final ModelTankFill modelTankFill = new ModelTankFill(); // one instance (each new one also compiled fresh display lists)
public void renderTileEntityAt(TileEntity te, double x, double y, double z, float floatt) {
GL11.glPushMatrix();
GL11.glTranslated(x + 0.5D, y + 0.001D, z + 0.5D);
Minecraft.getMinecraft().renderEngine.bindTexture(new ResourceLocation("thaumicadditions", "textures/models/TankLiquid/" + (int)(Minecraft.getSystemTime() % 1600L / 100L) + ".png"));
Minecraft.getMinecraft().renderEngine.bindTexture(LIQUID_FRAMES[(int)(Minecraft.getSystemTime() % 1600L / 100L)]);
GL11.glPushMatrix();
GL11.glRotatef(180.0F, 0.0F, 0.0F, 1.0F);
GL11.glPushMatrix();
@@ -29,7 +37,7 @@ public class RendererTankBasic extends TileEntitySpecialRenderer {
Color mesh = ColorUtil.blend(new Color(VisGrid.visColor), new Color(VisGrid.taintColor));
GL11.glColor3f((float)mesh.getRed() / 255.0F, (float)mesh.getGreen() / 255.0F, (float)mesh.getBlue() / 255.0F);
if(storedTot > 0.0F) {
(new ModelTankFill()).render((Entity)null, 0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F);
this.modelTankFill.render((Entity)null, 0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F);
}
}
@@ -2,7 +2,6 @@ package com.pengu.thaumcraft.additions.renderer;
import com.pengu.thaumcraft.additions.init.All;
import com.pengu.thaumcraft.additions.tileentity.TileThaumCrystallizer;
import java.awt.Color;
import java.util.Random;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityClientPlayerMP;
@@ -18,6 +17,8 @@ import thaumcraft.common.config.ConfigItems;
public class RendererThaumicCrystallizer extends TileEntitySpecialRenderer {
private final ModelCrystal crystal = new ModelCrystal(); // one instance (each new one also compiled a fresh display list)
public void renderTileEntityAt(TileEntity te, double x, double y, double z, float par1float) {
if(te instanceof TileThaumCrystallizer) {
TileThaumCrystallizer t = (TileThaumCrystallizer)te;
@@ -200,10 +201,9 @@ public class RendererThaumicCrystallizer extends TileEntitySpecialRenderer {
private void drawCrystal(int ori, float x, float y, float z, float a1, float a2, Random rand, int color, float id) {
EntityClientPlayerMP p = Minecraft.getMinecraft().thePlayer;
float shade = MathHelper.sin((float)p.ticksExisted % (9.0E16F + id * 16.0F)) * 0.025F + 0.825F;
Color c = new Color(color);
float r = (float)c.getRed() / 220.0F;
float g = (float)c.getGreen() / 220.0F;
float b = (float)c.getBlue() / 220.0F;
float r = (float)(color >> 16 & 255) / 220.0F;
float g = (float)(color >> 8 & 255) / 220.0F;
float b = (float)(color & 255) / 220.0F;
GL11.glPushMatrix();
GL11.glEnable(2977);
GL11.glEnable(3042);
@@ -218,7 +218,7 @@ public class RendererThaumicCrystallizer extends TileEntitySpecialRenderer {
int var21 = var19 / 65536;
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)var20 / 1.0F, (float)var21 / 1.0F);
GL11.glColor4f(r, g, b, 1.0F);
(new ModelCrystal()).render();
this.crystal.render();
GL11.glScalef(1.0F, 1.0F, 1.0F);
GL11.glDisable('\u803a');
GL11.glDisable(3042);
@@ -11,16 +11,19 @@ import org.lwjgl.opengl.GL11;
public class RendererThaumicGenerator extends TileEntitySpecialRenderer {
private static final ResourceLocation TEXTURE = new ResourceLocation("thaumicadditions", "textures/models/ThaumicGenerator.png");
private final ModelThaumicGenerator modelThaumicGenerator = new ModelThaumicGenerator(); // one instance (each new one also compiled fresh display lists)
public void renderTileEntityAt(TileEntity te, double x, double y, double z, float par1float) {
GL11.glPushMatrix();
GL11.glTranslatef((float)x + 0.5F, (float)y + 1.5F, (float)z + 0.5F);
ResourceLocation textures = new ResourceLocation("thaumicadditions", "textures/models/ThaumicGenerator.png");
ResourceLocation textures = TEXTURE;
Minecraft.getMinecraft().renderEngine.bindTexture(textures);
GL11.glPushMatrix();
GL11.glRotatef(180.0F, 0.0F, 0.0F, 1.0F);
GL11.glPushMatrix();
GL11.glRotatef(0.0F, 0.0F, 1.0F, 0.0F);
(new ModelThaumicGenerator()).render((Entity)null, 0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F, ((TileThaumicGenerator)te).emitPowerFromSidesListedHere);
this.modelThaumicGenerator.render((Entity)null, 0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F, ((TileThaumicGenerator)te).emitPowerFromSidesListedHere);
GL11.glPopMatrix();
GL11.glPopMatrix();
GL11.glPopMatrix();
@@ -10,16 +10,19 @@ import org.lwjgl.opengl.GL11;
public class RendererThaumicRestorer extends TileEntitySpecialRenderer {
private static final ResourceLocation TEXTURE = new ResourceLocation("thaumicadditions", "textures/models/ThaumicRestorer.png");
private final ModelThaumicRestorer modelThaumicRestorer = new ModelThaumicRestorer(); // one instance (each new one also compiled fresh display lists)
public void renderTileEntityAt(TileEntity te, double x, double y, double z, float par1float) {
GL11.glPushMatrix();
GL11.glTranslatef((float)x + 0.5F, (float)y + 1.5F, (float)z + 0.5F);
Minecraft.getMinecraft().renderEngine.bindTexture(new ResourceLocation("thaumicadditions", "textures/models/ThaumicRestorer.png"));
Minecraft.getMinecraft().renderEngine.bindTexture(TEXTURE);
GL11.glPushMatrix();
GL11.glRotatef(180.0F, 0.0F, 0.0F, 1.0F);
GL11.glPushMatrix();
GL11.glRotatef(0.0F, 0.0F, 1.0F, 0.0F);
GL11.glDisable(2896);
(new ModelThaumicRestorer()).render((Entity)null, 0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F);
this.modelThaumicRestorer.render((Entity)null, 0.0F, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F);
GL11.glEnable(2896);
GL11.glPopMatrix();
GL11.glPopMatrix();
@@ -35,6 +35,7 @@ public class TileCreativeNode extends TileVisNode implements INode, IWandable {
public Color targetColor = new Color(16777215);
public Color color = new Color(16777215);
public boolean hasUpdatedOnce;
private boolean locationRegistered;
public void updateEntity() {
@@ -44,12 +45,51 @@ public class TileCreativeNode extends TileVisNode implements INode, IWandable {
if(!this.hasUpdatedOnce) {
this.hasUpdatedOnce = !this.hasUpdatedOnce;
} else {
} else if(!this.locationRegistered || !this.isRegistrationIntact()) {
this.generateId();
}
}
/**
* True while the shared location map still holds this node's entry unchanged. The old code rewrote the entry every
* tick, which also repaired it after another mod cleared or altered the map; checking it is one lookup and four
* int compares, and generateId runs again as soon as the entry is missing or different.
*/
private boolean isRegistrationIntact() {
if(this.id == null || TileNode.locations == null || this.worldObj == null) {
return false;
}
java.util.List entry = (java.util.List)TileNode.locations.get(this.id);
if(entry == null || entry.size() != 4) {
return false;
}
return Integer.valueOf(this.worldObj.provider.dimensionId).equals(entry.get(0))
&& Integer.valueOf(this.xCoord).equals(entry.get(1))
&& Integer.valueOf(this.yCoord).equals(entry.get(2))
&& Integer.valueOf(this.zCoord).equals(entry.get(3));
}
public void invalidate() {
this.unregisterLocation();
super.invalidate();
}
public void onChunkUnload() {
this.unregisterLocation();
super.onChunkUnload();
}
private void unregisterLocation() {
if(this.id != null && TileNode.locations != null) {
TileNode.locations.remove(this.id);
}
this.locationRegistered = false;
}
public AspectList getAspects() {
return (new AspectList()).add(Aspect.AIR, 134217).add(Aspect.WATER, 134217).add(Aspect.FIRE, 134217).add(Aspect.ORDER, 134217).add(Aspect.ENTROPY, 134217).add(Aspect.EARTH, 134217);
}
@@ -232,6 +272,7 @@ public class TileCreativeNode extends TileVisNode implements INode, IWandable {
t.add(Integer.valueOf(this.yCoord));
t.add(Integer.valueOf(this.zCoord));
TileNode.locations.put(this.id, t);
this.locationRegistered = true;
}
return this.id;
@@ -35,25 +35,17 @@ public class TileHyperNodeCreator extends TileThaumcraft implements IInventory,
}
}
TileNode var5 = this.worldObj.getTileEntity(this.xCoord, this.yCoord + 1, this.zCoord) != null && this.worldObj.getTileEntity(this.xCoord, this.yCoord + 1, this.zCoord) instanceof TileNode?(TileNode)this.worldObj.getTileEntity(this.xCoord, this.yCoord + 1, this.zCoord):null;
net.minecraft.tileentity.TileEntity above = this.worldObj.getTileEntity(this.xCoord, this.yCoord + 1, this.zCoord);
TileNode var5 = above instanceof TileNode?(TileNode)above:null;
this.node = var5 != null;
if(this.node) {
AspectList list = new AspectList();
int corner;
for(corner = 0; corner < Aspect.getPrimalAspects().size(); ++corner) {
list.add((Aspect)Aspect.getPrimalAspects().get(corner), totalItems);
// the node is only rewritten when it no longer holds the wanted amounts (drained, or the stock changed)
if(!holdsExactly(var5.getAspects(), totalItems, this.primalsOnly)) {
var5.setAspects(wantedAspects(totalItems, this.primalsOnly));
}
if(!this.primalsOnly) {
for(corner = 0; corner < Aspect.getCompoundAspects().size(); ++corner) {
list.add((Aspect)Aspect.getCompoundAspects().get(corner), totalItems);
}
}
var5.setAspects(list);
if(this.worldObj.rand.nextBoolean()) {
corner = this.worldObj.rand.nextInt(8);
int corner = this.worldObj.rand.nextInt(8);
if(corner == 0) {
Thaumcraft.proxy.nodeBolt(this.worldObj, (float)this.xCoord, (float)this.yCoord + 2.0F, (float)this.zCoord, (float)this.xCoord + 0.5F, (float)this.yCoord + 1.5F, (float)this.zCoord + 0.5F);
}
@@ -90,6 +82,52 @@ public class TileHyperNodeCreator extends TileThaumcraft implements IInventory,
}
/** The aspect list a node above gets: every primal (and unless primalsOnly every compound) at {@code total}. */
public static AspectList wantedAspects(int total, boolean primalsOnly) {
AspectList list = new AspectList();
int i;
for(i = 0; i < Aspect.getPrimalAspects().size(); ++i) {
list.add((Aspect)Aspect.getPrimalAspects().get(i), total);
}
if(!primalsOnly) {
for(i = 0; i < Aspect.getCompoundAspects().size(); ++i) {
list.add((Aspect)Aspect.getCompoundAspects().get(i), total);
}
}
return list;
}
/** Whether {@code current} already equals {@link #wantedAspects(int, boolean)} without building it. */
public static boolean holdsExactly(AspectList current, int total, boolean primalsOnly) {
if(current == null) {
return false;
}
int expected = Aspect.getPrimalAspects().size() + (primalsOnly?0:Aspect.getCompoundAspects().size());
return current.size() == expected && allAmounts(current, total, primalsOnly);
}
private static boolean allAmounts(AspectList current, int total, boolean primalsOnly) {
for(int i = 0; i < Aspect.getPrimalAspects().size(); ++i) {
if(current.getAmount((Aspect)Aspect.getPrimalAspects().get(i)) != total) {
return false;
}
}
if(!primalsOnly) {
for(int i = 0; i < Aspect.getCompoundAspects().size(); ++i) {
if(current.getAmount((Aspect)Aspect.getCompoundAspects().get(i)) != total) {
return false;
}
}
}
return true;
}
public static boolean areItemStacksEqual(ItemStack s1, ItemStack s2) {
return s1 == null && s2 == null?true:s1 != null && s2 != null && s1.getItem() == s2.getItem() && s1.getItemDamage() == s2.getItemDamage();
}
@@ -1,7 +1,6 @@
package com.pengu.thaumcraft.additions.tileentity;
import com.pengu.thaumcraft.additions.tileentity.TileCreativeNode;
import java.util.Calendar;
import java.util.Random;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.Tessellator;
@@ -14,13 +13,19 @@ import org.lwjgl.opengl.GL11;
public class TileRendererCreativeNode extends TileEntitySpecialRenderer {
private static final ResourceLocation[] AURA = new ResourceLocation[]{new ResourceLocation("thaumicadditions", "textures/models/aura_1.png"), new ResourceLocation("thaumicadditions", "textures/models/aura_2.png")};
// Re-seeded per node each frame: setSeed gives the same sequence as new Random(seed)
private final Random rnd = new Random();
public void renderTileEntityAt(TileEntity te, double x, double y, double z, float floay) {
boolean wearsRevealer = false;
ItemStack helmet = Minecraft.getMinecraft().thePlayer.inventory.armorItemInSlot(0);
if(te instanceof TileCreativeNode) {
TileCreativeNode tcn = (TileCreativeNode)te;
Random rnd = new Random((long)(tcn.getId() + "" + tcn.yCoord).hashCode() ^ 256L);
float rot = (float)(Calendar.getInstance().get(14) + rnd.nextInt(1000)) % 1000.0F;
Random rnd = this.rnd;
rnd.setSeed((long)(tcn.getId() + "" + tcn.yCoord).hashCode() ^ 256L);
// millisecond of the current second, as Calendar.getInstance().get(MILLISECOND) gave
float rot = (float)((int)(System.currentTimeMillis() % 1000L) + rnd.nextInt(1000)) % 1000.0F;
boolean prevBlend = GL11.glIsEnabled(3042);
if(!prevBlend) {
GL11.glEnable(3042);
@@ -31,7 +36,7 @@ public class TileRendererCreativeNode extends TileEntitySpecialRenderer {
GL11.glTranslated(x + 0.5D, y + 0.15000000596046448D, z + 0.5D);
GL11.glEnable('\u803a');
GL11.glScalef(1.5F, 1.5F, 1.5F);
Minecraft.getMinecraft().getTextureManager().bindTexture(new ResourceLocation("thaumicadditions", "textures/models/aura_" + (rnd.nextInt(2) + 1) + ".png"));
Minecraft.getMinecraft().getTextureManager().bindTexture(AURA[rnd.nextInt(2)]);
Tessellator p_77026_1_ = Tessellator.instance;
float f = 0.0F;
float f1 = 1.0F;
@@ -2,11 +2,8 @@ package com.pengu.thaumcraft.additions.tileentity;
import com.pengu.thaumcraft.additions.init.All;
import com.pengu.thaumcraft.additions.utils.Util;
import java.lang.reflect.Method;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
import net.minecraftforge.common.IPlantable;
import net.minecraftforge.common.util.ForgeDirection;
import thaumcraft.api.TileThaumcraft;
@@ -17,24 +14,29 @@ public class TileTaintedCrops extends TileThaumcraft {
public int tick = 0;
/** Ticks of growth needed per stage; the taint biome grows faster. */
public static int growthThreshold(boolean taintBiome) {
return 4000 - (taintBiome?450:0);
}
/** Growth only counts while the crop is not yet fully grown. */
public static boolean countsGrowth(int meta) {
return meta < 4;
}
public void updateEntity() {
if(!this.worldObj.getBlock(this.xCoord, this.yCoord - 1, this.zCoord).canSustainPlant(this.worldObj, this.xCoord, this.yCoord - 1, this.zCoord, ForgeDirection.UP, (IPlantable)All.B_taint_crops) && this.worldObj.getBlock(this.xCoord, this.yCoord - 1, this.zCoord) != Blocks.grass && this.worldObj.getBlock(this.xCoord, this.yCoord - 1, this.zCoord) != Blocks.dirt) {
net.minecraft.block.Block soil = this.worldObj.getBlock(this.xCoord, this.yCoord - 1, this.zCoord);
if(!soil.canSustainPlant(this.worldObj, this.xCoord, this.yCoord - 1, this.zCoord, ForgeDirection.UP, (IPlantable)All.B_taint_crops) && soil != Blocks.grass && soil != Blocks.dirt) {
// the crop block is gone after this, so there is nothing left to drop
this.worldObj.setBlockToAir(this.xCoord, this.yCoord, this.zCoord);
try {
Method m = this.worldObj.getBlock(this.xCoord, this.yCoord, this.zCoord).getClass().getDeclaredMethod("dropBlockAsItem", new Class[]{World.class, Integer.class, Integer.class, Integer.class, ItemStack.class});
m.setAccessible(true);
m.invoke(this.worldObj.getBlock(this.xCoord, this.yCoord, this.zCoord), new Object[]{this.worldObj, Integer.valueOf(this.xCoord), Integer.valueOf(this.yCoord), Integer.valueOf(this.zCoord), null});
} catch (Throwable var2) {
;
}
} else {
if(this.worldObj.getBlockMetadata(this.xCoord, this.yCoord, this.zCoord) < 4) {
int meta = this.worldObj.getBlockMetadata(this.xCoord, this.yCoord, this.zCoord);
if(countsGrowth(meta)) {
++this.tick;
}
if(this.tick >= 4000 - (this.worldObj.getBiomeGenForCoords(this.xCoord, this.zCoord).biomeID == Config.biomeTaintID?450:0)) {
// the lowest possible threshold is 3550, so the biome is only looked up once it matters
if(this.tick >= growthThreshold(true) && this.tick >= growthThreshold(this.worldObj.getBiomeGenForCoords(this.xCoord, this.zCoord).biomeID == Config.biomeTaintID)) {
Util.setBlockMetadata(this.worldObj, this.xCoord, this.yCoord, this.zCoord, this.worldObj.getBlockMetadata(this.xCoord, this.yCoord, this.zCoord) + 1);
}
@@ -23,21 +23,17 @@ public class TileTankBasic extends TileThaumcraft implements ITubable {
this.capacity = 1005;
}
/** Block metadata for a tank by which neighbours are tanks: 0 none, 1 only below, 2 only above, 3 both. */
public static int connectionMeta(boolean above, boolean below) {
return (above?2:0) | (below?1:0);
}
public void updateEntity() {
if(!(this.worldObj.getBlock(this.xCoord, this.yCoord + 1, this.zCoord) instanceof BlockTankBasic) && !(this.worldObj.getBlock(this.xCoord, this.yCoord - 1, this.zCoord) instanceof BlockTankBasic) && this.worldObj.getBlockMetadata(this.xCoord, this.yCoord, this.zCoord) != 0) {
Util.setBlockMetadata(this.worldObj, this.xCoord, this.yCoord, this.zCoord, 0);
}
if(!(this.worldObj.getBlock(this.xCoord, this.yCoord + 1, this.zCoord) instanceof BlockTankBasic) && this.worldObj.getBlock(this.xCoord, this.yCoord - 1, this.zCoord) instanceof BlockTankBasic && this.worldObj.getBlockMetadata(this.xCoord, this.yCoord, this.zCoord) != 1) {
Util.setBlockMetadata(this.worldObj, this.xCoord, this.yCoord, this.zCoord, 1);
}
if(this.worldObj.getBlock(this.xCoord, this.yCoord + 1, this.zCoord) instanceof BlockTankBasic && !(this.worldObj.getBlock(this.xCoord, this.yCoord - 1, this.zCoord) instanceof BlockTankBasic) && this.worldObj.getBlockMetadata(this.xCoord, this.yCoord, this.zCoord) != 2) {
Util.setBlockMetadata(this.worldObj, this.xCoord, this.yCoord, this.zCoord, 2);
}
if(this.worldObj.getBlock(this.xCoord, this.yCoord + 1, this.zCoord) instanceof BlockTankBasic && this.worldObj.getBlock(this.xCoord, this.yCoord - 1, this.zCoord) instanceof BlockTankBasic && this.worldObj.getBlockMetadata(this.xCoord, this.yCoord, this.zCoord) != 3) {
Util.setBlockMetadata(this.worldObj, this.xCoord, this.yCoord, this.zCoord, 3);
boolean above = this.worldObj.getBlock(this.xCoord, this.yCoord + 1, this.zCoord) instanceof BlockTankBasic;
boolean below = this.worldObj.getBlock(this.xCoord, this.yCoord - 1, this.zCoord) instanceof BlockTankBasic;
int wantedMeta = TileTankBasic.connectionMeta(above, below);
if(this.worldObj.getBlockMetadata(this.xCoord, this.yCoord, this.zCoord) != wantedMeta) {
Util.setBlockMetadata(this.worldObj, this.xCoord, this.yCoord, this.zCoord, wantedMeta);
}
if(!this.worldObj.isRemote) {
@@ -50,14 +46,17 @@ public class TileTankBasic extends TileThaumcraft implements ITubable {
}
}
boolean var4 = this.worldObj.getTileEntity(this.xCoord, this.yCoord + 1, this.zCoord) instanceof TileTankBasic && this.vis + this.taint < this.capacity;
// each neighbour tile is looked up once; nothing between here and the uses changes the blocks around
net.minecraft.tileentity.TileEntity aboveTile = this.worldObj.getTileEntity(this.xCoord, this.yCoord + 1, this.zCoord);
boolean var4 = aboveTile instanceof TileTankBasic && this.vis + this.taint < this.capacity;
if(var4 && this.taint + this.vis > this.capacity - 5) {
MagicType var5 = Math.max(this.taint, this.vis) == this.vis?MagicType.VIS:MagicType.TAINT;
this.ejectVis(var5, ((ITubable)this.worldObj.getTileEntity(this.xCoord, this.yCoord + 1, this.zCoord)).acceptVis(var5, var5 == MagicType.VIS?this.vis:this.taint, ForgeDirection.DOWN), ForgeDirection.UP);
this.ejectVis(var5, ((ITubable)aboveTile).acceptVis(var5, var5 == MagicType.VIS?this.vis:this.taint, ForgeDirection.DOWN), ForgeDirection.UP);
}
if(this.worldObj.getTileEntity(this.xCoord, this.yCoord - 1, this.zCoord) instanceof TileTankBasic) {
TileTankBasic var6 = (TileTankBasic)this.worldObj.getTileEntity(this.xCoord, this.yCoord - 1, this.zCoord);
net.minecraft.tileentity.TileEntity belowTile = this.worldObj.getTileEntity(this.xCoord, this.yCoord - 1, this.zCoord);
if(belowTile instanceof TileTankBasic) {
TileTankBasic var6 = (TileTankBasic)belowTile;
if(var6.vis + var6.taint < var6.capacity - 5) {
for(int i = 5; i > 0; --i) {
if(this.vis >= i && var6.vis + var6.taint + i <= this.capacity - 5) {
@@ -10,11 +10,26 @@ import com.pengu.util.ForgeDirectionHelper;
import cpw.mods.fml.common.Loader;
import java.util.ArrayList;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.ForgeDirection;
import thaumcraft.api.TileThaumcraft;
public class TileThaumicGenerator extends TileThaumcraft implements ITubable {
private static final ForgeDirection[] DIRS = new ForgeDirection[]{ForgeDirection.UP, ForgeDirection.DOWN, ForgeDirection.EAST, ForgeDirection.WEST, ForgeDirection.SOUTH, ForgeDirection.NORTH};
private static final boolean BOTANIA_LOADED = Loader.isModLoaded("Botania");
private static Botania botania;
// Botania bridge is stateless: one instance, created only when Botania is loaded
private static Botania botania() {
if(botania == null) {
botania = new Botania();
}
return botania;
}
public int amount = 0;
public int maxAmount = 640;
public DirectionCombo emitPowerFromSidesListedHere;
@@ -25,7 +40,7 @@ public class TileThaumicGenerator extends TileThaumcraft implements ITubable {
}
public void updateEntity() {
ForgeDirection[] dirs = new ForgeDirection[]{ForgeDirection.UP, ForgeDirection.DOWN, ForgeDirection.EAST, ForgeDirection.WEST, ForgeDirection.SOUTH, ForgeDirection.NORTH};
ForgeDirection[] dirs = DIRS;
this.maxAmount = 640;
ArrayList fd = new ArrayList();
int i;
@@ -59,31 +74,31 @@ public class TileThaumicGenerator extends TileThaumcraft implements ITubable {
if(this.amount > 1) {
for(i = 0; i < dirs.length; ++i) {
if(this.worldObj.getTileEntity(this.xCoord + ForgeDirectionHelper.getForgeDirectionXApplyed(dirs[i]), this.yCoord + ForgeDirectionHelper.getForgeDirectionYApplyed(dirs[i]), this.zCoord + ForgeDirectionHelper.getForgeDirectionZApplyed(dirs[i])) != null) {
if(this.worldObj.getTileEntity(this.xCoord + ForgeDirectionHelper.getForgeDirectionXApplyed(dirs[i]), this.yCoord + ForgeDirectionHelper.getForgeDirectionYApplyed(dirs[i]), this.zCoord + ForgeDirectionHelper.getForgeDirectionZApplyed(dirs[i])) instanceof IRJReceiver) {
// one tile lookup per side (it was read up to nine times)
TileEntity te = this.worldObj.getTileEntity(this.xCoord + ForgeDirectionHelper.getForgeDirectionXApplyed(dirs[i]), this.yCoord + ForgeDirectionHelper.getForgeDirectionYApplyed(dirs[i]), this.zCoord + ForgeDirectionHelper.getForgeDirectionZApplyed(dirs[i]));
if(te != null) {
if(te instanceof IRJReceiver) {
fd.add(dirs[i]);
}
if(this.worldObj.getTileEntity(this.xCoord + ForgeDirectionHelper.getForgeDirectionXApplyed(dirs[i]), this.yCoord + ForgeDirectionHelper.getForgeDirectionYApplyed(dirs[i]), this.zCoord + ForgeDirectionHelper.getForgeDirectionZApplyed(dirs[i])) instanceof IEnergyReceiver) {
if(te instanceof IEnergyReceiver) {
fd.add(dirs[i]);
}
if(Loader.isModLoaded("Botania") && (new Botania()).canConnect(this.worldObj, this.xCoord, this.yCoord, this.zCoord, dirs[i])) {
if(BOTANIA_LOADED && botania().canConnect(this.worldObj, this.xCoord, this.yCoord, this.zCoord, dirs[i])) {
fd.add(dirs[i]);
}
}
if(this.worldObj.getTileEntity(this.xCoord + ForgeDirectionHelper.getForgeDirectionXApplyed(dirs[i]), this.yCoord + ForgeDirectionHelper.getForgeDirectionYApplyed(dirs[i]), this.zCoord + ForgeDirectionHelper.getForgeDirectionZApplyed(dirs[i])) != null) {
if(this.worldObj.getTileEntity(this.xCoord + ForgeDirectionHelper.getForgeDirectionXApplyed(dirs[i]), this.yCoord + ForgeDirectionHelper.getForgeDirectionYApplyed(dirs[i]), this.zCoord + ForgeDirectionHelper.getForgeDirectionZApplyed(dirs[i])) instanceof IRJReceiver) {
this.amount -= ((IRJReceiver)this.worldObj.getTileEntity(this.xCoord + ForgeDirectionHelper.getForgeDirectionXApplyed(dirs[i]), this.yCoord + ForgeDirectionHelper.getForgeDirectionYApplyed(dirs[i]), this.zCoord + ForgeDirectionHelper.getForgeDirectionZApplyed(dirs[i]))).receiveRJ(dirs[i], 2000, false) / 1000;
if(te instanceof IRJReceiver) {
this.amount -= ((IRJReceiver)te).receiveRJ(dirs[i], 2000, false) / 1000;
}
if(this.worldObj.getTileEntity(this.xCoord + ForgeDirectionHelper.getForgeDirectionXApplyed(dirs[i]), this.yCoord + ForgeDirectionHelper.getForgeDirectionYApplyed(dirs[i]), this.zCoord + ForgeDirectionHelper.getForgeDirectionZApplyed(dirs[i])) instanceof IEnergyReceiver) {
this.amount -= ((IEnergyReceiver)this.worldObj.getTileEntity(this.xCoord + ForgeDirectionHelper.getForgeDirectionXApplyed(dirs[i]), this.yCoord + ForgeDirectionHelper.getForgeDirectionYApplyed(dirs[i]), this.zCoord + ForgeDirectionHelper.getForgeDirectionZApplyed(dirs[i]))).receiveEnergy(dirs[i], 2000, false) / 1000;
if(te instanceof IEnergyReceiver) {
this.amount -= ((IEnergyReceiver)te).receiveEnergy(dirs[i], 2000, false) / 1000;
}
if(Loader.isModLoaded("Botania")) {
this.amount -= (new Botania()).handleManaGen(this.worldObj, this.xCoord, this.yCoord, this.zCoord, dirs[i], 2000) / 100;
if(BOTANIA_LOADED) {
this.amount -= botania().handleManaGen(this.worldObj, this.xCoord, this.yCoord, this.zCoord, dirs[i], 2000) / 100;
}
}
}
@@ -24,8 +24,8 @@ public class TileTileBooster extends TileThaumcraft {
int x = this.xCoord + ForgeDirectionHelper.getForgeDirectionXApplyed(fd);
int y = this.yCoord + ForgeDirectionHelper.getForgeDirectionYApplyed(fd);
int z = this.zCoord + ForgeDirectionHelper.getForgeDirectionZApplyed(fd);
TileEntity te = this.worldObj.getTileEntity(x, y, z) != null && !(this.worldObj.getTileEntity(x, y, z) instanceof TileTileBooster)?this.worldObj.getTileEntity(x, y, z):null;
if(te != null && te.canUpdate()) {
TileEntity te = this.worldObj.getTileEntity(x, y, z); // read once (was up to three times)
if(te != null && !(te instanceof TileTileBooster) && te.canUpdate()) {
for(int i = 0; i < this.speed; ++i) {
te.updateEntity();
}
@@ -3,7 +3,6 @@ package com.pengu.thaumcraft.additions.utils.hud;
import com.google.common.base.Stopwatch;
import com.pengu.api.thaumicadditions.items.IHUDRenderable;
import com.pengu.thaumcraft.additions.init.All;
import com.pengu.thaumcraft.additions.utils.Util;
import com.pengu.thaumcraft.additions.utils.hud.TipMessage;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
@@ -98,14 +97,7 @@ public class HUD {
GL11.glTranslated(-0.0D, -(using?50.0D:0.0D), -0.0D);
}
if(player.getItemInUse() != null) {
ItemStack using1 = player.getItemInUse();
maxDuration = using1.getItem().getMaxItemUseDuration(using1);
duration = player.getItemInUseDuration();
drawTexturedModalRect(HudLocation, Minecraft.getMinecraft().displayWidth / 8 - 32, 0, 0, 33, 65, 17);
i = duration * 65 / Math.max(1, Util.applyModule(maxDuration));
drawTexturedModalRect(HudLocation, Minecraft.getMinecraft().displayWidth / 8 - 31, 0, 1, 50, i, 17);
}
// 物品使用进度条已删除:displayWidth / 8 不考虑界面缩放,条会偏到屏幕左上角,Ethyn 决定不画。
if(this.currentMessage != null) {
this.currentMessage.render();
@@ -0,0 +1,159 @@
package com.pengu.thaumcraft.additions.entity;
import static org.junit.Assert.assertEquals;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.item.ItemStack;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.world.World;
import net.minecraft.world.WorldProviderSurface;
import net.minecraft.world.WorldServer;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import thaumcraft.common.CommonProxy;
import thaumcraft.common.Thaumcraft;
/** TDLM/thaumicadditions#21: a grounded singularity queries its pull box once per tick, not 256 times. */
public class EntitySingularityQueryTest {
private CommonProxy originalProxy;
private QueryWorld world;
private EntitySingularity singularity;
private Entity bystander;
private Mob mob;
@SuppressWarnings("unchecked")
private static <T> T allocate(Class<T> type) throws Exception {
Constructor<?> ctor = sun.reflect.ReflectionFactory.getReflectionFactory()
.newConstructorForSerialization(type, Object.class.getDeclaredConstructor());
return (T) ctor.newInstance();
}
@Before
public void setUp() throws Exception {
this.originalProxy = Thaumcraft.proxy;
Thaumcraft.proxy = new CommonProxy();
this.world = allocate(QueryWorld.class);
this.world.rand = new Random(3);
this.world.all = new ArrayList<Entity>();
this.world.living = new ArrayList<Entity>();
Field provider = World.class.getDeclaredField("provider");
provider.setAccessible(true);
provider.set(this.world, new WorldProviderSurface());
this.singularity = allocate(EntitySingularity.class);
this.singularity.worldObj = this.world;
this.singularity.posX = 8;
this.singularity.posY = 64;
this.singularity.posZ = 8;
this.singularity.radius = 10;
Field ground = net.minecraft.entity.projectile.EntityThrowable.class.getDeclaredField("inGround");
ground.setAccessible(true);
ground.setBoolean(this.singularity, true);
this.bystander = allocate(Plain.class);
this.bystander.posX = 12;
this.bystander.posY = 66;
this.bystander.posZ = 5;
this.mob = allocate(Mob.class);
this.mob.posX = 4;
this.mob.posY = 63;
this.mob.posZ = 11;
this.world.all.add(this.bystander);
this.world.all.add(this.mob);
this.world.living.add(this.mob);
}
@After
public void tearDown() {
Thaumcraft.proxy = this.originalProxy;
}
@Test
public void thePullBoxIsQueriedOncePerTickAndEntitiesAreStillPulled() {
this.singularity.onUpdate();
assertEquals("entity queries over the pull box", 2, this.world.pullQueries);
double lift = 1 / 400.0F * 4.0F;
assertEquals((8 - 12) / 10.0D, this.bystander.motionX, 1e-9);
assertEquals((64 - 66 + lift) / 10.0D, this.bystander.motionY, 1e-9);
assertEquals((8 - 5) / 10.0D, this.bystander.motionZ, 1e-9);
assertEquals((8 - 4) / 10.0D, this.mob.motionX, 1e-9);
assertEquals((64 - 63 + lift) / 10.0D, this.mob.motionY, 1e-9);
assertEquals((8 - 11) / 10.0D, this.mob.motionZ, 1e-9);
}
public static class Plain extends Entity {
public Plain() {
super(null);
}
@Override
protected void entityInit() {}
@Override
protected void readEntityFromNBT(net.minecraft.nbt.NBTTagCompound nbt) {}
@Override
protected void writeEntityToNBT(net.minecraft.nbt.NBTTagCompound nbt) {}
}
public static class Mob extends EntityLivingBase {
public Mob() {
super(null);
}
@Override
public ItemStack getHeldItem() {
return null;
}
@Override
public ItemStack getEquipmentInSlot(int slot) {
return null;
}
@Override
public void setCurrentItemOrArmor(int slot, ItemStack stack) {}
@Override
public ItemStack[] getLastActiveItems() {
return new ItemStack[0];
}
}
public static class QueryWorld extends WorldServer {
List<Entity> all;
List<Entity> living;
int pullQueries;
QueryWorld() {
super(null, null, "singularity", 0, null, null);
}
@Override
public List getEntitiesWithinAABB(Class type, AxisAlignedBB box) {
if (box.maxX - box.minX < 3.0D) {
return new ArrayList();
}
this.pullQueries++;
return new ArrayList(type == EntityLivingBase.class ? this.living : this.all);
}
@Override
public Block getBlock(int x, int y, int z) {
return null; // equals Blocks.air, which is unset without a Minecraft bootstrap
}
}
}
@@ -0,0 +1,113 @@
package com.pengu.thaumcraft.additions.tileentity;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import net.minecraft.world.World;
import net.minecraft.world.WorldProviderSurface;
import net.minecraft.world.WorldServer;
import org.junit.Before;
import org.junit.Test;
import thaumcraft.common.tiles.TileNode;
/** TDLM/thaumicadditions#17: a creative node registers its location once, not every tick, and unregisters on removal. */
public class CreativeNodeRegistryTest {
private TileCreativeNode node;
@SuppressWarnings("unchecked")
private static <T> T allocate(Class<T> type) throws Exception {
Constructor<?> ctor = sun.reflect.ReflectionFactory.getReflectionFactory()
.newConstructorForSerialization(type, Object.class.getDeclaredConstructor());
return (T) ctor.newInstance();
}
@Before
public void setUp() throws Exception {
if (TileNode.locations == null) {
Field f = TileNode.class.getDeclaredField("locations");
f.setAccessible(true);
f.set(null, new HashMap<String, ArrayList>());
}
TileNode.locations.clear();
World world = allocate(FixtureWorld.class);
Field provider = World.class.getDeclaredField("provider");
provider.setAccessible(true);
provider.set(world, new WorldProviderSurface());
this.node = allocate(TileCreativeNode.class);
this.node.setWorldObj(world);
this.node.xCoord = 3;
this.node.yCoord = 70;
this.node.zCoord = 5;
}
@Test
public void locationIsPutOnceAcrossManyTicks() {
this.node.updateEntity(); // first tick only marks the node as updated
this.node.updateEntity();
ArrayList first = TileNode.locations.get("0:3:70:5");
assertNotNull(first);
for (int i = 0; i < 1000; i++) {
this.node.updateEntity();
}
assertSame("no re-registration on later ticks", first, TileNode.locations.get("0:3:70:5"));
assertEquals(1, TileNode.locations.size());
}
@Test
public void unloadingRemovesTheLocationSoItCanBeRegisteredAgain() {
this.node.updateEntity();
this.node.updateEntity();
assertNotNull(TileNode.locations.get("0:3:70:5"));
this.node.onChunkUnload();
assertNull(TileNode.locations.get("0:3:70:5"));
this.node.updateEntity();
assertNotNull(TileNode.locations.get("0:3:70:5"));
}
@Test
public void aClearedMapIsRepairedOnTheNextTick() {
this.node.updateEntity();
this.node.updateEntity();
assertNotNull(TileNode.locations.get("0:3:70:5"));
TileNode.locations.clear(); // another mod or TC4 wipes the shared map
this.node.updateEntity();
assertNotNull(TileNode.locations.get("0:3:70:5"));
}
@Test
public void anAlteredEntryIsRestoredOnTheNextTick() {
this.node.updateEntity();
this.node.updateEntity();
ArrayList wrong = new ArrayList();
wrong.add(Integer.valueOf(9));
wrong.add(Integer.valueOf(9));
wrong.add(Integer.valueOf(9));
wrong.add(Integer.valueOf(9));
TileNode.locations.put("0:3:70:5", wrong);
this.node.updateEntity();
assertEquals(Integer.valueOf(3), TileNode.locations.get("0:3:70:5").get(1));
}
@Test
public void anIntactEntryIsNotRewritten() {
this.node.updateEntity();
this.node.updateEntity();
ArrayList first = TileNode.locations.get("0:3:70:5");
this.node.updateEntity();
assertSame(first, TileNode.locations.get("0:3:70:5"));
}
public static class FixtureWorld extends WorldServer {
FixtureWorld() {
super(null, null, "node", 0, null, null);
}
}
}
@@ -0,0 +1,47 @@
package com.pengu.thaumcraft.additions.tileentity;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import thaumcraft.api.aspects.Aspect;
import thaumcraft.api.aspects.AspectList;
/** TDLM/thaumicadditions#16: the node is only rewritten when it no longer holds what the creator wants. */
public class HyperNodeCreatorAspectsTest {
@Test
public void aFreshlyBuiltListIsRecognisedAsCurrent() {
for (boolean primalsOnly : new boolean[] { false, true }) {
for (int total : new int[] { 0, 1, 64, 5000 }) {
AspectList list = TileHyperNodeCreator.wantedAspects(total, primalsOnly);
assertTrue("total " + total + " primalsOnly " + primalsOnly,
TileHyperNodeCreator.holdsExactly(list, total, primalsOnly));
}
}
}
@Test
public void wantedListHasTheSameShapeAsBefore() {
AspectList all = TileHyperNodeCreator.wantedAspects(7, false);
assertEquals(Aspect.getPrimalAspects().size() + Aspect.getCompoundAspects().size(), all.size());
assertEquals(7, all.getAmount(Aspect.getPrimalAspects().get(0)));
assertEquals(Aspect.getPrimalAspects().size(), TileHyperNodeCreator.wantedAspects(7, true).size());
}
@Test
public void aDrainedOrChangedNodeIsRewritten() {
AspectList list = TileHyperNodeCreator.wantedAspects(10, false);
list.reduce(Aspect.getPrimalAspects().get(0), 3);
assertFalse(TileHyperNodeCreator.holdsExactly(list, 10, false));
assertFalse(TileHyperNodeCreator.holdsExactly(TileHyperNodeCreator.wantedAspects(10, false), 11, false));
assertFalse(TileHyperNodeCreator.holdsExactly(TileHyperNodeCreator.wantedAspects(10, true), 10, false));
assertFalse(TileHyperNodeCreator.holdsExactly(null, 10, false));
}
@Test
public void primalsOnlyDoesNotMatchAnUnrelatedFullList() {
assertFalse(TileHyperNodeCreator.holdsExactly(TileHyperNodeCreator.wantedAspects(10, false), 10, true));
}
}
@@ -0,0 +1,32 @@
package com.pengu.thaumcraft.additions.tileentity;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
/** TDLM/thaumicadditions#20 and #22: the lookups were hoisted without changing what the tiles decide. */
public class TankAndCropLogicTest {
@Test
public void tankMetadataMatchesTheOriginalFourBranches() {
assertEquals(0, TileTankBasic.connectionMeta(false, false));
assertEquals(1, TileTankBasic.connectionMeta(false, true));
assertEquals(2, TileTankBasic.connectionMeta(true, false));
assertEquals(3, TileTankBasic.connectionMeta(true, true));
}
@Test
public void cropThresholdIsLowerInTheTaintBiome() {
assertEquals(4000, TileTaintedCrops.growthThreshold(false));
assertEquals(3550, TileTaintedCrops.growthThreshold(true));
}
@Test
public void cropOnlyCountsGrowthBelowStageFour() {
assertTrue(TileTaintedCrops.countsGrowth(0));
assertTrue(TileTaintedCrops.countsGrowth(3));
assertFalse(TileTaintedCrops.countsGrowth(4));
}
}
@@ -0,0 +1,153 @@
package com.pengu.thaumcraft.additions.tileentity;
import static org.junit.Assert.assertEquals;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraft.world.WorldProviderSurface;
import net.minecraft.world.WorldServer;
import org.junit.Test;
/** TDLM/thaumicadditions#20: a tank looks each neighbour tile up once per tick and moves vis/taint exactly as before. */
public class TileTankBasicLookupTest {
@SuppressWarnings("unchecked")
private static <T> T allocate(Class<T> type) throws Exception {
Constructor<?> ctor = sun.reflect.ReflectionFactory.getReflectionFactory()
.newConstructorForSerialization(type, Object.class.getDeclaredConstructor());
return (T) ctor.newInstance();
}
public static class CountingWorld extends WorldServer {
Map<Long, TileEntity> tiles;
int tileLookups;
int blockLookups;
CountingWorld() {
super(null, null, "tanks", 0, null, null);
}
static long key(int x, int y, int z) {
return ((long) x << 40) ^ ((long) y << 20) ^ z;
}
@Override
public TileEntity getTileEntity(int x, int y, int z) {
this.tileLookups++;
return this.tiles.get(key(x, y, z));
}
@Override
public Block getBlock(int x, int y, int z) {
this.blockLookups++;
return null; // equals Blocks.air, which is unset without a Minecraft bootstrap
}
@Override
public int getBlockMetadata(int x, int y, int z) {
this.blockLookups++;
return 0;
}
}
private static CountingWorld world() throws Exception {
CountingWorld world = allocate(CountingWorld.class);
world.rand = new Random(1);
Field provider = World.class.getDeclaredField("provider");
provider.setAccessible(true);
provider.set(world, new WorldProviderSurface());
world.isRemote = true; // no taint explosion branch
world.tiles = new HashMap<Long, TileEntity>();
return world;
}
private static TileTankBasic tank(CountingWorld world, int y, int vis, int taint) throws Exception {
TileTankBasic tank = allocate(TileTankBasic.class);
tank.setWorldObj(world);
tank.xCoord = 3;
tank.yCoord = y;
tank.zCoord = 5;
tank.capacity = 1005;
tank.vis = vis;
tank.taint = taint;
world.tiles.put(CountingWorld.key(3, y, 5), tank);
return tank;
}
/** The lookups of the old method, in order, on the same fields. */
private static void referenceUpdate(TileTankBasic t) {
World w = t.getWorldObj();
w.getBlock(t.xCoord, t.yCoord + 1, t.zCoord);
w.getBlock(t.xCoord, t.yCoord - 1, t.zCoord);
w.getBlockMetadata(t.xCoord, t.yCoord, t.zCoord);
boolean var4 = w.getTileEntity(t.xCoord, t.yCoord + 1, t.zCoord) instanceof TileTankBasic && t.vis + t.taint < t.capacity;
if (var4 && t.taint + t.vis > t.capacity - 5) {
TileTankBasic above = (TileTankBasic) w.getTileEntity(t.xCoord, t.yCoord + 1, t.zCoord);
int type = Math.max(t.taint, t.vis) == t.vis ? 0 : 1;
int q = above.acceptVis(type == 0 ? com.pengu.api.thaumicadditions.tubesyst.ITubable.MagicType.VIS : com.pengu.api.thaumicadditions.tubesyst.ITubable.MagicType.TAINT,
type == 0 ? t.vis : t.taint, net.minecraftforge.common.util.ForgeDirection.DOWN);
t.ejectVis(type == 0 ? com.pengu.api.thaumicadditions.tubesyst.ITubable.MagicType.VIS : com.pengu.api.thaumicadditions.tubesyst.ITubable.MagicType.TAINT, q,
net.minecraftforge.common.util.ForgeDirection.UP);
}
if (w.getTileEntity(t.xCoord, t.yCoord - 1, t.zCoord) instanceof TileTankBasic) {
TileTankBasic var6 = (TileTankBasic) w.getTileEntity(t.xCoord, t.yCoord - 1, t.zCoord);
if (var6.vis + var6.taint < var6.capacity - 5) {
for (int i = 5; i > 0; --i) {
if (t.vis >= i && var6.vis + var6.taint + i <= t.capacity - 5) {
var6.vis += i;
t.vis -= i;
}
if (t.taint >= i && var6.vis + var6.taint + i <= t.capacity - 5) {
var6.taint += i;
t.taint -= i;
}
}
}
}
}
private static int[] state(TileTankBasic... tanks) {
int[] out = new int[tanks.length * 2];
for (int i = 0; i < tanks.length; i++) {
out[2 * i] = tanks[i].vis;
out[2 * i + 1] = tanks[i].taint;
}
return out;
}
@Test
public void aStackOfTanksEndsInTheSameStateWithFewerLookups() throws Exception {
Random rnd = new Random(9);
for (int round = 0; round < 40; round++) {
int[] seedValues = new int[6];
for (int i = 0; i < 6; i++) {
seedValues[i] = rnd.nextInt(1000);
}
CountingWorld oldWorld = world();
CountingWorld newWorld = world();
TileTankBasic[] oldTanks = new TileTankBasic[3];
TileTankBasic[] newTanks = new TileTankBasic[3];
for (int i = 0; i < 3; i++) {
oldTanks[i] = tank(oldWorld, 64 + i, seedValues[2 * i], seedValues[2 * i + 1] % 500);
newTanks[i] = tank(newWorld, 64 + i, seedValues[2 * i], seedValues[2 * i + 1] % 500);
}
for (int tick = 0; tick < 30; tick++) {
for (int i = 0; i < 3; i++) {
referenceUpdate(oldTanks[i]);
newTanks[i].updateEntity();
}
org.junit.Assert.assertArrayEquals("round " + round + " tick " + tick, state(oldTanks), state(newTanks));
}
org.junit.Assert.assertTrue("the old method looks up at least as often", oldWorld.tileLookups >= newWorld.tileLookups);
assertEquals("new: two tile lookups per tank per tick", 2 * 3 * 30, newWorld.tileLookups);
assertEquals(oldWorld.blockLookups, newWorld.blockLookups);
}
}
}