跳到正文
烈焰甘蔗Wiki

Scan System

The scan system captures what a player observes with the Thaumometer, recording block, entity, and phenomena scans as ScanResult objects. Custom scan handlers can be registered to extend what the Thaumometer can detect.

ScanResult

Package: thaumcraft.api.research

Records the outcome of a single scan operation.

Fields

Field Type Description
type byte Scan type: 1 = blocks, 2 = entities, 3 = phenomena
id int Block ID (type 1) or 0
meta int Block metadata (type 1) or 0
entity Entity The scanned entity (type 2) or null
phenomena String Custom phenomena identifier (type 3)

Constructor

public ScanResult(byte type, int blockId, int blockMeta, Entity entity, String phenomena)
  • Type 1 (block): Pass blockId, blockMeta, null, null
  • Type 2 (entity): Pass 0, 0, entity, null
  • Type 3 (phenomena): Pass 0, 0, null, phenomena

Equality

Two ScanResult objects are equal when their type matches and:

  • Type 1: Same id and meta
  • Type 2: Same entity ID (entity.getEntityId())
  • Type 3: Same phenomena string
@Override
public boolean equals(Object obj) {
    if (obj instanceof ScanResult) {
        ScanResult sr = (ScanResult) obj;
        if (type != sr.type) return false;
        if (type == 1 && (id != sr.id || meta != sr.meta)) return false;
        if (type == 2 && entity.getEntityId() != sr.entity.getEntityId()) return false;
        if (type == 3 && !phenomena.equals(sr.phenomena)) return false;
    }
    return true;
}

IScanEventHandler

Package: thaumcraft.api.research

Interface for custom scan handlers. Implement this to extend Thaumometer functionality, for example to detect mod-specific phenomena that cannot be represented as plain blocks or entities.

public interface IScanEventHandler {
    ScanResult scanPhenomena(ItemStack stack, World world, EntityPlayer player);
}
Parameter Type Description
stack ItemStack The ItemStack held by the player (e.g., the Thaumometer)
world World The world in which the scan is performed
player EntityPlayer The player performing the scan

Returns a ScanResult if the handler recognizes something to record, or null if nothing applicable.

Registration

ThaumcraftApi.registerScanEventhandler(IScanEventHandler handler)

Add to your FMLPostInitializationEvent handler. Multiple handlers can be registered; they are called in registration order until one returns a non-null result.

⚠️ 补充订正(原条目严重漏项):本 API 自带的 javadoc 明确声明该注册功能当前不可用。 证据:ThaumcraftApi.java:95 原文 @param handler ... not really working atm, so ignore it for now 紧接着 ThaumcraftApi.java:96-97 又有 @deprecated Thaumcraft removed this function. Infusion and research are now handled differently 该方法体(ThaumcraftApi.java:98)目前是空实现,只往静态 scanEventHandlers 列表里 add 一下。 结论:不要依赖它。 本条目原版把它当作正常可用的注册点描述,与源码不符,已订正。

「多个 handler 按注册顺序调用、直到某个返回非 null 为止」这句无法从本仓核实—— 遍历调用逻辑在主 mod 侧,本仓只有 IScanEventHandler 接口(research/IScanEventHandler.java:8, 单一方法 ScanResult scanPhenomena(ItemStack, World, EntityPlayer))和 add-only 的注册方法。


Entity Scanning Tags

Thaumcraft also maintains a registry of aspects associated with entity types, used for both scanning and calculating vis drops.

EntityTags Inner Class

public static class EntityTags {
    public EntityTags(String entityName, AspectList aspects, EntityTagsNBT... nbts)

    public String entityName;       // e.g., "Skeleton"
    public EntityTagsNBT[] nbts;    // Optional NBT match conditions
    public AspectList aspects;      // Aspects associated with this entity
}

public static class EntityTagsNBT {
    public EntityTagsNBT(String name, Object value)
    public String name;  // NBT key
    public Object value; // Expected value
}

Registration

public static void registerEntityTag(String entityName, AspectList aspects, EntityTagsNBT... nbt)
Parameter Description
entityName Entity registry name (e.g., "Skeleton")
aspects AspectList of aspects for this entity
nbt Optional NBT-based conditions to distinguish variants

Examples

// All skeletons share these aspects
ThaumcraftApi.registerEntityTag("Skeleton",
    new AspectList().add(Aspect.DEATH, 5).add(Aspect.UNDEAD, 3));

// Wither skeleton has different aspects (NBT differentiates it)
ThaumcraftApi.registerEntityTag("Skeleton",
    new AspectList().add(Aspect.DEATH, 8).add(Aspect.UNDEAD, 5),
    new EntityTagsNBT("SkeletonType", (byte) 1));

Thaumometer Scan Process

  1. Player right-clicks with a Thaumometer equipped
  2. Ray-trace identifies target block, entity, or look-at point
  3. Type 1 (block): Thaumcraft looks up block ID + metadata
  4. Type 2 (entity): Thaumcraft records the entity
  5. Type 3 (phenomena): Custom IScanEventHandler instances are queried in order; first non-null result wins
  6. Result is compared against the player’s known scans; new unique scans grant research progress

Custom Phenomena Handler Example

public class MyModScanHandler implements IScanEventHandler {
    @Override
    public ScanResult scanPhenomena(ItemStack stack, World world, EntityPlayer player) {
        // Example: detect when player looks at a specific mod block
        MovingObjectPosition mop = ThaumcraftApiHelper.rayTraceIgnoringSource(
            world, player.posVec, player.getLook(1f), false, false, false);
        if (mop != null && mop.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK) {
            Block block = world.getBlock(mop.blockX, mop.blockY, mop.blockZ);
            if (block == MyModBlocks.mysteriousBlock) {
                return new ScanResult((byte) 3, 0, 0, null, "mymod.mystery");
            }
        }
        return null;
    }
}

// Registration
ThaumcraftApi.registerScanEventhandler(new MyModScanHandler());
浏览全部模组